ホストクラスはポリシークラスをテンプレートパラメータとして受け取る。ポリシークラスをホストクラスへと結合する方法には、主として合成と継承の2通りの方法がある。
合成による結合では、ポリシークラスのオブジェクトをホストクラスのデータメンバにする。以下に例を示す。
例 5.2. 合成によるポリシークラスとホストクラスの結合
class policy_A
{
public:
void func() { std::cout << "policy_A" << std::endl; }
};
template <class P>
class host
{
private:
P policy_;
public:
void func() { policy_.func(); }
};
実装方法としては素直だが、後述する通り継承による結合に比べていくつかの点で劣る。
継承による結合では、ポリシークラスをホストクラスの基底クラスにする。以下に例を示す。
例 5.3. 継承によるポリシークラスとホストクラスの結合
class policy_A
{
protected:
void func() { std::cout << "policy_A" << std::endl; }
};
template <class P>
class host
: public P
{
public:
void func() { P::func(); }
};
やや技巧的であることが難点だが、合成による結合に比べて次の点で優れている。
ポリシークラスがホストクラスに任意の公開インタフェースを追加できる
ホストクラスがポリシークラスをpublic継承するようにした上で、ポリシークラスの実体にpublicメンバを追加することで行える。ポリシークラスのpublicメンバは、ホストクラスが明示的に隠蔽しない限りホストクラスのpublicメンバになる。
空の基底クラスのサイズを0にする最適化(empty base classes optimization, EBO)を行える
C++の言語規約上、オブジェクトのサイズは常に1以上であると決められている。例えば、ホストクラスが1つのポリシークラスを合成により結合するという構成で、空クラスがポリシークラスとして与えられたとき、ホストクラスのオブジェクト内にはそのポリシークラスのオブジェクトために少なくともサイズ1の領域が確保される。継承による結合では、その領域のサイズを0にする最適化が行われる可能性がある。
ポリシークラスのオブジェクトの生成を禁止できる
ポリシークラスのデストラクタをprotectedにすることで行える。これにより、ポリシークラスの実体化は派生クラスの一部としてのみ行えるということをコード上で表現できる。
ポリシークラスとホストクラスの結合インタフェースは、ほとんどの場合継承による結合の方が有利である。
ポリシークラスに対して内部状態を持ってはならないという制約を課す場合は、継承と合成以外の選択肢がある。 項5.3. 「ステートレスポリシー」を参照のこと。