テンプレートの世界では、実行時チェックを行う代わりに、型ごとにテンプレートを特殊化するだけでよいでしょう。
template<typename T>
void foo(T obj);
template<>
void foo<MyClassA>(MyClassA obj) {
}
template<>
void foo<MyClassB>(MyClassB obj2) {
}
これにより、コンパイラは引数を推測することにより、コンパイル時に正しいテンプレートを生成できます。
これは、インスタンスの static type に基づいてのみ解決されることに注意してください。つまり、変数がMyClassC
から継承されるMyClassB
ため、ジェネリック形式を使用する必要があるというコンパイル時の知識はありません。したがって、これは機能しません:
MyClassC* cinstance = new MyClassC();
foo(cinstance); //compiler error, no specialization for MyClassC
一般に、これは、コンパイル時ポリモーフィズムと実行時ポリモーフィズムが非常に異なるシステムであるという一般的なルールを示しています。テンプレートは、継承の知識がなくても静的な型の領域を厳密に扱います。これは、2 つの機能がよりシームレスに統合されている Java/C# から来た人々を驚かせるかもしれません。
クラスの機能を実行時に特化する場合、オプションは次のとおりです。
- 仮想メソッドの定義 -- この機能の一部が本当にこのオブジェクトの一部であるかどうかによっては、適切ではない可能性があります
- dynamic_cast (あなたが現在行っていること) を使用してください。やや眉をひそめていますが、誰もが得られる最も簡単な解決策になる可能性があります。
- ビジター パターン-- オーバーロードを使用して、実行時に正しい型の関数に解決する設計パターン。