テンプレートでの型保障された汎用リストの使い方
クラス テンプレートの概要:インデックス への移動
同じような内容の記述が繰り返し必要な場合は,テンプレートを使うことをまず考えてください。次のような汎用リストクラスのクラス定義には注意が必要です。
class GList
{
public:
void insert( void * );
void *peek();
.
.
.
};
このクラス定義には型保障がなく,この問題を解決するにはクラス定義を毎回繰り返さなければなりません。型チェックなしで挿入が行われるので,どのような結果が得られるかわからないためです。この型保障の問題を解決するには,これを包合するクラスを記述します。
class FooList : public GList {
public:
void insert( Foo *f ) { GList::insert( f ); }
Foo *peek() { return (Foo *)GList::peek(); }
.
.
.
};
これで型保障は万全です。insert は Foo へのポインタ型または Foo からの派生オブジェクト型の引数しかとらないので,基礎となるコンテナが保持するポインタは,Foo 型のものしか指しません。したがって,FooList::peek() への型変換は常に保障され,FooList が作成されます。BarList,BazList などの場合も,それぞれにクラス定義の繰り返しが必要ですが,ここでテンプレートをもう一度使えば繰り返しが避けられ,同時に型を保障することができます。詳細については,型保障された汎用リストクラスの例を参照してください。C++ の STL(Standard Template Library)には,型保証されたコレクションクラスが豊富に含まれています。
テンプレートを使えば,必要に応じてどのような型保障リストも簡単な宣言で作成できます。各ラッパークラスからの型変換で生成されるコードはないので,この型保障による実行時のオーバーヘッドはありません。