C++ ではクラスは実装を定義するとともにインターフェイスを宣言することにも使われる。
プライベートメンバ関数は、クラスの「インターフェイス」ではないにもかかわらず、クラス利用者に見えるようにクラスの中で宣言しなくてはいけない。
プライベートデータメンバの宣言やプライベート関数のシグネチャを変更すると、利用者のコードも再コンパイルしなくてはいけなくなる。
したがって、クラスの実装からインターフェイスを分離し、不必要な再コンパイルを防ぐのは有用である。
 
abstractionを2つの実装クラスに分離する。
ひとつは識別子としての役割をし、利用者に対してクラスインターフェイスとなる。
これは''ハンドル''と呼ばれる。
他方のクラスは、実装を具体化し、''ボディ''と呼ばれる。
ハンドルはメンバ関数の実行をボディにフォワードする。
// String.hppファイル
class StringRep; // 前方宣言のみ
class String {
  public:
    String();
    String(const String &s);
    String &operator=(const String &s);
    ~String();
    String(const char *s);
    . . . .
  private:
      StringRep *rep; // ポインタで実装する (pimpl)
};
// String.hppファイル ここまで
// String.cppファイル
namespace { // 無名名前空間
  class StringRep {
    // このクラスの定義はクライアントからは見えないようにし、
    // Stringクラスとは別々のソースファイルとしてコンパイルされるべき。
    friend class String;
    StringRep(const char *s);
    ~StringRep();
    int count; char *rep;
  };
} // 無名名前空間終わり
String::String() // コンストラクタや、その他諸々の定義
. . . .
これにより、実装（ボディ）に対して安全にデータの変更を行うことができ、ハンドルの利用者は再コンパイルの必要がない。
実装はポインタの影に「より隠される」ので、コンパイルファイアウォールとも呼ばれる。
ひとつ回り道をするのでコストがかかる。
このイディオムはディープコピーやシャロウコピー、あるいはそのほかの実行時の動作には関知しない。計数ボディ(Counted Body)、/封筒・便箋(Envelope Letter)/を参照のこと。
このイディオムを使うと継承があまり役に立たなくなる。この欠点を補うにはHandle Body Hierarchyを参照のこと。
このクラスはボディの動的なメモリ確保に制限がある。計数ボディ(Counted Body)を参照。
また、まれに、封筒・便箋(Envelope Letter)やスマートポインタ(Smart Pointer)で述べられているハンドルとボディの冗長な更新の必要が生じる。
 
 
 
Original copyright ©1998 Lucent Technologies, Bell Labs Innovations. All rights reserved. Permission granted to reprint verbatim for non-commercial use provided this copyright notice appears. (Contents edited for Wikibooks).
]]