以下に示すコードは、同じ公開インタフェースを持つ2つのポリシークラスと、それを受け入れるホストクラスと、ホストクラスを用いるクライアントコードの例である。
例 5.1. ポリシークラスとホストクラス
class policy_A
{
protected:
void func() { std::cout << "policy_A" << std::endl; }
};
class policy_B
{
protected:
void func() { std::cout << "policy_B" << std::endl; }
};
template <class P>
class host
: public P
{
public:
void func() { P::func(); }
};
void foo()
{
host<policy_A> A;
host<policy_B> B;
A.func(); // "policy_A" を表示
B.func(); // "policy_B" を表示
}
policy_Aとpolicy_Bは、どちらもメンバ関数funcを持つクラスである。hostは、メンバ関数funcを持つクラスを第1パラメータに取るクラステンプレートである。hostのメンバ関数funcは、テンプレートパラメータPに指定されたクラスのメンバ関数funcに処理を任せているため、その振る舞いは指定されたクラスによって変わる。hostにとってpolicy_Aとpolicy_Bはポリシークラスであり、policy_Aとpolicy_Bにとってhostはホストクラスである。
ホストクラスに対してポリシークラスを指定するのはクライアントコードfooである。fooの実装者は、上記の例のようにhostに対してpolicy_Aとpolicy_Bのどちらを与えてもよい。のhost<...>funcメンバ関数を呼び出したときの振る舞いは、与えられたポリシークラスによって決定される。また、fooの実装者はメンバ関数funcを持つクラスpolicy_Cを新たに定義し、それをポリシークラスとして与えることもできる。
このように、ポリシークラスはクライアントコードのコンパイル時にホストクラスの振る舞いを決定する。これを静的多態性という。ポリシークラスとホストクラスの組み合わせは静的多態性の代表的な実現手段のひとつである。仮想関数に代表される動的多態性とは異なり、静的多態性には実行時オーバヘッドがないという利点がある。一方、コンパイル時間が長くなるという欠点がある。
上記の例では、ポリシークラスはホストクラスのメンバ関数の振る舞いだけを制御する。だが他にも、アルゴリズムやデータ構造、型定義などを制御するよう構成することもできる。何を持ってポリシークラスと呼ぶのかという明確な定義はないが、振る舞いの制御を強調したものを通常はポリシークラスと呼ぶ。