あるオブジェクトに対する各関数呼び出し前後で、透過的に(全ての関数について同じ)何らかの動作を実行するスマートポインタオブジェクトを提供する。Execute Around Sequences - Kevlin Henney
スマートポインタの二重適用
しばしば、あるクラスのメンバ関数呼び出しの度に、何らかの機能を実行する必要がある場合がある。
例えば、マルチスレッドアプリケーションでは、データ構造を変更する前にロックし、その後でロックを解除しなくてはならない。
データ構造の可視化アプリケーションでは、毎回の挿入・削除操作後のデータ構造のサイズに興味があるかもしれない。
using namespace std;
class Visualizer {
    std::vector  & vect;
  public:
    Visualizer (vector &v) : vect(v) {}
    void data_changed () {
       std::cout << "現在のサイズ: " << vect.size();
    }
};
int main () // データ可視化アプリケーション
{
  std::vector  vector;
  Visualizer visu (vector);
  //...
  vector.push_back (10);
  visu.data_changed ();
  vector.push_back (20);
  visu.data_changed ();
  // もっとたくさんの insert/remove の呼び出しと
  // 対応する可視化コードの呼び出し
}
このような関数呼び出しの繰り返しはエラーを招きやすく退屈である。
自動的に可視化コードが呼び出されるのが理想だろう。
Visualizer は std::list についても同様にも使われうるだろう。
このように、単一のクラスの一部分ではなく、むしろ複数のクラスに渡るものは、一般にアスペクト(aspect)として知られている。
このイディオムは、単純なアスペクトを設計し実装するのに有用である。
class VisualizableVector {
  public:
    class proxy {
      public:
        proxy (vector *v) : vect (v) {
          std::cout << "呼び出し前のサイズ: " << vect->size ();
        }
        vector * operator -> () {
          return vect;
        }
        ~proxy () {
          std::cout << "呼び出し後のサイズ: " << vect->size ();
        }
      private:
        vector  * vect;
    };
    VisualizableVector (vector *v) : vect(v) {}    
    proxy operator -> () {
       return proxy (vect);
    }
  private:
    vector  * vect;
};
int main()
{
  VisualizableVector vector (new vector);
  //...
  vector->push_back (10); // . 演算子ではなく -> 演算子が使われていることに注意せよ
  vector->push_back (20);
}
VisualizableVector のオーバーロードされた -> 演算子は一時的な proxy オブジェクトを生成し、返す。
proxy オブジェクトのコンストラクタでは vector のサイズをログ出力する。
その後、proxy オブジェクトのオーバーロードされた -> 演算子が呼び出され、
ベースとしている vector オブジェクトに対する素のポインタを返すことによって、
単に vector オブジェクトに呼び出しを転送する。
vector への実際の呼び出しが終了した後、proxy のデストラクタが再びサイズをログ出力する。
このように、可視化用のログは透過的であり、main 関数はぐちゃぐちゃにならずに済む。
このイディオムは、より汎用的で強力な Execute Around Proxy idiom の特別な場合である。
賢くテンプレートと組み合わせ、オーバーロードされた -> 演算子を連鎖させた時に、
このイディオムの真の力が現れる。
template 
class Aspect
{
  protected:
    Aspect (Para p): para_(p) {}
    Para  para_;
  public:
    NextAspect operator -> () 
    {
      return para_;
    }
};
template 
struct Visualizing : Aspect 
{
  public:
    Visualizing (Para p) 
       : Aspect  (p) 
    {
	std::cout << "可視化アスペクト前" << std::endl;
    }
    ~Visualizing () 
    {
	std::cout << "可視化アスペクト後" << std::endl;
    }
};
template 
struct Locking : Aspect 
{
  public:
    Locking (Para p) 
       : Aspect  (p) 
    {
		std::cout << "ロックアスペクト前" << std::endl;
    }
    ~Locking () 
    {
	std::cout << "ロックアスペクト後" << std::endl;
    }
};
template 
struct Logging : Aspect 
{
  public:
    Logging (Para p) 
        : Aspect  (p) 
    {
		std::cout << "ログアスペクト前" << std::endl;
    }
    ~Logging () 
    {
	std::cout << "ログアスペクト後" << std::endl;
    }
};
template 
class AspectWeaver 
{
public:
    AspectWeaver (Para p) : para_(p) {}    
    Aspect operator -> () 
    {
       return Aspect (para_);
    }
private:
	Para para_;
};
int main()
{ 
  AW3(Visualizing, Locking, Logging, vector  *) 
	  X (new vector);
  //...
  X->push_back (10); // . 演算子ではなく -> 演算子が使われていることに注意せよ
  X->push_back (20);
  return 0;
}
スマートポインタ(Smart Pointer)
More C++ Idioms/Execute-Around Pointer
]]