2012-04-30 13 views
0

私はクラスに固有の機能を追加したテンプレート、持っている:実行時にC++で継承ツリーを検索するにはどうすればよいですか?

class Base 
{}; 

class Derived1 : public Base 
{}; 

class Derived2 : public Derived1 
{}; 

... 

しかし、どこかでツリー内の「後方がある:それから私は、標準的なツリー状の継承を持って

template <Class ReceiverOfAbility> 
class Able : public ReceiverOfAbility, SomeOtherClass 
{ 
... 
} 

をブランチ」

class Derived2WithAbility : public Able<Derived2> 
{}; 

は私が持っていると仮定します。

Base* basePointer = new DerivedWithAbility; 

実行時にbasePointerSomeOtherClassにキャストするにはどうすればよいですか? dynamic_castは機能しません。問題は、多くの派生クラスが存在することであり、ツリー内でクラスがその能力を継承するフォワードにはわからないということです。 Ableからの継承が発生した場所をツリー内で検索する必要があります。

アイデア?

EDIT:

私は

dynamic_cast<SomeOtherClass*>(dynamic_cast<Derived2WithAbility*>(basePointer)) 

しようとしましたが、私が手:

error: ‘SomeOtherClass’ is an inaccessible base of ‘Derived2WithAbility’ 

任意のアイデアなぜですか?

+2

テンプレートはコンパイル時の構造です。具体化のためのコードを検索する方が理にかなっています。 – AJG85

答えて

6
class Able : public ReceiverOfAbility, SomeOtherClass 

SomeOtherClassAble<whatever>プライベート基底クラスです。 dynamic_castを機能させるには(すなわち、SomeOtherClassへのキャストに成功するために)、公開されている必要があります。

+0

あなたはそうです! クラスを使用しましたありがとう、私は決してprivateへの継承 "defaults"を認識しませんでした。 –

+2

@MartinDrozdikは、クラスのprivate、structsのpublicをデフォルトとしています。 – juanchopanza

1

実行時にbasePointerをSomeOtherClassにキャストするにはどうすればよいですか? dynamic_castは機能しません。

dynamic_castを使用する必要があります。それが "うまくいかない"場合は、キャストすることはできません。 dynamic_castは、Baseクラスに少なくとも1つの仮想関数がある場合にのみ機能します(仮想デストラクタがそのトリックを行う必要があります)。

私はAbleからの継承が発生する場所をツリー内で検索する必要があります。

私が知る限り、RTTIはクラスに「継承」情報を提供していません。ただし、デバッガで継承情報​​を確認できる場合があります。この情報の可用性はデバッガによって異なります。

--EDIT--

あなたはprivate継承を使用してSomeOtherClassから継承します。継承を公開すると、それは機能します。

+0

アドバイスをいただきありがとうございます。 Baseに仮想デストラクタがあることを確認しました。しかし、それはまだ動作しません。 –

+0

@MartinDrozdik: "SomeOtherClass"には仮想メソッドが含まれていますか? dynamic_castは仮想メソッドのないクラスでは動作しません。 – SigTerm

+0

はい、それでも動作しません:( –

1

私はあなたの継承ツリーをスキャンすることをお勧めしません。 vtableを介さについてはこの記事を参照してくださいし、それもあなたのコードを経由して

http://kaisar-haque.blogspot.com/2008/07/c-accessing-virtual-table.html

をアクセス見ていない私は、デバッグ中に、これは有用である見ることができますが、実行時にそれを当てにすることはできません。

複数の継承が複雑で、複数の基底クラスから継承するクラスがあるため、派生したオブジェクトを指す共通の基底クラスのルートを見つけることは、このような状況では髪の毛が出ることがあります。あなたの遺産の継承権を再考する以外に、本当の答えはありません。継承の代わりに合成を使用して、単一の継承ツリーに固執できますか?それは物事をはるかに簡単にするでしょう。

+1

C++はABIを定義していないので、このアプローチはコンパイラ間でも同じコンパイラでも動作することは保証されません。 –

関連する問題