2013-04-21 5 views
7

私は、抽象基本クラスParentとサブクラスChild1とChild2を持っているとします。私が親*を取る関数を持っている場合、実行時に関数が実際に受け取ったChild1 *かChild2 *かどうかを判断するための方法(おそらくRTTI?)がありますか?基本クラスへのポインタを指定してサブクラスを特定していますか?

fooがParent *の場合、typeid(foo)はfooのメンバである子クラスに関係なくtypeid(Parent *)を返します。

+2

「親*」は常に「親*」です。 *決して*子*ではありません。あなたが尋ねることは、「それが指すもののタイプは何か」です。 –

+0

Kerrek SB:昨日は冷たい肩をあげましたが、実際のプログラミングに慣れたとき、あなたのコメントはおそらくページの他のものよりも貴重でした。申し訳ありません... – ExOttoyuhr

答えて

5

あなたは間接参照ポインタ、ポインタではなく、それ自体の型IDを見てする必要があります。つまり、typeid(* foo)ではなく、typeid(foo)です。逆参照されたポインタについて質問すると、動的な型が得られます。ポインタ自体について尋ねると、あなたが見ているように静的な型が得られます。

+0

多くのサブクラスポインタを作成するよりも、私が探していたより正確にフィットするように思えます。 – ExOttoyuhr

+0

'typeid(* foo)'は正しいランタイム型( '親クラスに少なくとも1つの仮想メソッドがある場合は、 'Parent'ではなく' Child1'です)。 – ApproachingDarknessFish

2

確か:

BaseClass *bptr = // whatever, pointer to base class 
SubclassOne *safe_ptr_one = dynamic_cast<SubclassOne *>(bptr); 
if (safe_ptr_one != nullptr) { 
    // Instance of SubclassOne 
} else { 
    // not an instance of SubclassOne, try the other one 
    SubclassTwo *safe_ptr_two = dynamic_cast<SubclassTwo *>(bptr); 
    if (safe_ptr_two != nullptr) { 
     // Instance of SubclassTwo 
    } else { 
     // it wasn't either one :'(
    } 
} 
+0

ニース - 私はdynamic_castがそれを行うことができたか分からなかった! (しかし、それが私が尋ねた理由です) – ExOttoyuhr

+0

@ExOttoyuhrよろしくお願いします。 And yy、Andy Prowlの前に答えを出しました! –

5

あなたはこのためにstd::dynamic_castを使用することができます。あなたはスマートポインタを使用している場合

Parent* ptr = new Child1(); 
if(dynamic_cast<Child1*>(ptr) != nullptr) { 
    // ptr is object of Child1 class 
} else if(dynamic_cast<Child2*>(ptr) != nullptr) { 
    // ptr is object of Child2 class 
} 

また、std::shared_ptrのように、あなたはこのようにそれを確認することができます:

std::shared_ptr<Parent> ptr(new Child1()); 
if(std::dynamic_pointer_cast<Child1>(ptr) != nullptr) { 
    // ptr is object of Child1 class 
} else if(std::dynamic_pointer_cast<Child2>(ptr) != nullptr) { 
    // ptr is object of Child2 class 
} 
関連する問題