18

クラス階層があるとしましょう。下部に Base があり、上部に Derived があります。基底クラスのポインタに変換されてもオブジェクトクラスを判別する方法。

Base* b = new Derived():

typeid(b).name(); // i want this to tell me that this is actually derived not base object

文字列フィールドなどと仮想 get 関数を手動で実装する以外に方法はありますか?

PS: コンパイラに依存しないソリューションについて話している

4

2 に答える 2

32

基本クラスに少なくとも 1 つの仮想メソッドがあることを確認<typeinfo>し、追加の逆参照だけで現在のコードを含めて使用しますtypeid(*b).name()


typeidちなみに、呼び出しは、明確に定義された動作で nullpointer を逆参照できる C++ の 1 つの場所であることに注意してください。これは、例外をスローできることを意味します 。

C++11 §5.2.8/2 :
「単項演算子をポインターに適用することによって glvalue 式が取得され*、ポインターが null ポインター値である場合 (4.10)、typeid式は例外をスローしstd::bad_typeidます (18.7.3)。」

于 2013-04-09T09:22:44.950 に答える
16

b実際に を指しているかどうかを調べたいDerivedだけの場合は、次のように使用しますdynamic_cast()

if (dynamic_cast<Derived*>(b)) { ... }

dynamic_castが指すオブジェクトの実際の実行時型が でbはない場合Derived(または から派生したクラスDerived) は、null ポインタを返します。name()のメンバーとは異なりstd::type_info、これはコンパイラ不変です。

Baseこれは、少なくとも 1 つの仮想メンバー関数がある場合にのみ機能することに注意してください。とにかく、ベースポインターを介して派生した型を操作しているため、仮想デストラクタが必要です。

于 2013-04-09T09:32:24.570 に答える