0

クラスに特定の機能を追加するテンプレートがあります。

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

次に、標準的なツリーのような継承があります。

class Base
{};

class Derived1 : public Base
{};

class Derived2 : public Derived1
{};

...

しかし、木のどこかに「後方分岐」があります

class Derived2WithAbility : public Able<Derived2>
{};

私が持っているとしましょう:

 Base* basePointer = new DerivedWithAbility;

basePointer実行時にどのようにキャストできSomeOtherClassますか?dynamic_cast動作しません。問題は、派生クラスがたくさんあることであり、ツリーのどこでクラスが機能を継承するのかがわかりません。継承が発生する場所をツリーで検索する必要がありAbleます。

何か案は?

編集:

私がしようとしました

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

しかし、私は得ます:

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

なぜアイデアはありますか?

4

3 に答える 3

6
class Able : public ReceiverOfAbility, SomeOtherClass

SomeOtherClassプライベート基本クラスですAble<whatever>。動作する(つまり、正常dynamic_castにキャストできるようにするSomeOtherClass)には、パブリックベースである必要があります。

于 2012-04-30T19:51:43.067 に答える
1

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

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

エイブルからの継承が発生する場所をツリーで検索する必要があります。

私の知る限り、RTTIはクラスの「継承」情報を提供しません。ただし、デバッガーで継承情報​​を表示できる場合があります。もちろん、この情報が利用できるかどうかはデバッガーによって異なります。

- 編集 -

プライベート継承を使用してSomeOtherClassから継承します。継承を公開すれば、機能します。

于 2012-04-30T19:31:40.007 に答える
1

継承ツリーをスキャンするのは良い考えではないと思います。vtablesの通過については、この投稿を参照してください。コードからアクセスできるようには見えません。

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

これはデバッグに役立つことがわかりますが、実行時に期待することはできません。

あなたが遭遇しているのは、多重継承が複雑である理由だと思います。複数の基本クラスから継承するクラスがあるため、派生オブジェクトを指す共通の基本クラスルートを見つけると、このような状況で問題が発生する可能性があります。相続の階層を再考する以外に、本当の答えはありません。継承の代わりに合成を使用して、単一の継承ツリーに固執することはできますか?それは物事をはるかに簡単にするでしょう。

于 2012-04-30T19:41:33.947 に答える