扱っているサブクラスのタイプを知る必要はありません。扱っているクラスのタイプをチェックする必要がある場合は、ポリモーフィズムを正しく実行していません。ポリモーフィズムの要点は、ifを減らし、コードをより柔軟にすることです。
知っておく必要がある場合があり、そのためにRTTIを使用できます。ただし、特に多くのパフォーマンスが必要な場合(ゲームやグラフィックプログラムなど)は、そうしないことをお勧めします。
演算子を使用してtypeid
、クラスに関する情報を取得し、クラスが特定のタイプであるかどうかを判別します。
例えば:
Animal* animal1 = new Cat;
if(typeid(animal1) == typeid(Cat))
{
cout << "animal1 is a: " << typeid(Cat).name();
}
次に、を使用static_cast
して階層の下にキャストします。
Animal* animal1 = new Cat;
if(typeid(animal1) == typeid(Cat))
{
Cat* cat = static_cast<Cat*>(animal1);
cat->scratchTheLivingHellOutOfYou();
}
dynamic_cast
または、typeid / static_castよりもはるかに安全ですが、はるかに遅いを使用できます。そのようです:
Animal* animal1 = new Cat;
if(Cat* cat = dynamic_cast<Cat*>(animal1)
{
cat->scratchTheLivingHellOutOfYou();
}
編集:
dynamic_cast
それが特定のタイプであるかどうかをテストしてキャストするよりも少し余分な作業をしなければならないという理由だけで遅くなります。つまり、dyanmic_cast
と同等ではありませんtypeid/static_cast
が、ほとんど同等です。
たとえば、2レベルを超える深さの階層を想像してみてください。
class Animal { /* ... */ }; // Base
class Cat : public Animal { /* ... */ }; // 2nd level
class Tiger : public Cat { /* ... */ }; // 3rd level
Catクラスで、すべてのCatに固有のメソッドが呼び出されたとしますscratchTheLivingHellOutOfYou()
。また、次のように言いましょう。動物のリストがあり、リストscratchTheLivingHellOutOfYou()
内のすべての猫を呼び出したいと思います(これには、クラスCatから派生したクラスが含まれます)。typeid
演算子とが使用されている場合、現在のタイプをチェックするだけで階層を気にしないstatic_cast
ため、これは必要なことを達成しません。typeid
このためにはdynamic_cast
、クラスが基本クラスから派生しているかどうかをチェックし、それに応じて階層を上下にキャストするため、を使用する必要があります。
この簡単な例は、C++でここに表示されます。プログラムの出力は次のとおりです。
USING TYPEID
*scratch*
meoyawnn!
RAWR
USING DYNAMIC_CAST
*scratch*
meoyawnn!
*scratch*
RAWR
したがって、これは単純なやdynamic_cast
よりもはるかに多くの作業を行うことがはっきりとわかります。階層を検索して、それが特定のタイプであるかどうかを確認します。簡単に言えば...階層を上下にキャストできます。一方、とは階層を特定のタイプにキャストすることしかできません。typeid
static_cast
dynamic_cast
dynamic_cast
typeid
static_cast
dynamic_cast
失敗した場合はNULLポインターを返すか、参照で使用している場合は例外をスローすることをお伝えしたいと思います。
ノート:
- 本当にパフォーマンスが必要で、ポリモーフィックオブジェクトのタイプをチェックする必要がある場合は、テンプレート/マクロなどを使用してクラスを識別するなど、RTTIに代わるものを見つけることをお勧めします。
dynamic_cast
オブジェクトが変換先のタイプであるかどうかわからない場合にのみ使用してください。プログラマーとして、キャストするものが100%そのタイプになることstatic_cast
を知っている場合は、を使用します。たとえば、animal1がthenになることがわかっている場合は、より適切です。Cat
static_cast