如何在运行时搜索C ++中的继承树?

时间:2012-04-30 19:25:48

标签: c++ inheritance

我有一个模板,它为类增加了一个特定的能力:

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强制转换为SomeOtherClassdynamic_cast不起作用。问题是会有很多派生类,我不知道在树中哪个类继承了这个能力。我需要在树中搜索Able继承的地方。

有什么想法吗?

编辑:

我试过

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

但我明白了:

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

任何想法为什么?

3 个答案:

答案 0 :(得分:6)

class Able : public ReceiverOfAbility, SomeOtherClass

SomeOtherClass私有基类Able<whatever>。要使dynamic_cast能够正常工作(即能够成功投射到SomeOtherClass),它必须是公共基础。

答案 1 :(得分:1)

  

如何在运行时将basePointer转换为SomeOtherClass? dynamic_cast不起作用。

您必须使用dynamic_cast。如果它“不起作用”,那么你就无法施放。仅当Base类至少有一个虚函数时,dynamic_cast才会起作用(虚拟析构函数应该可以解决)。

  

我需要在树中搜索Able继承的地方。

据我所知,RTTI不提供类的“继承”信息。但是,您可以在调试器中查看继承信息。当然,这些信息的可用性取决于调试器。

- 编辑 -

使用私有继承从SomeOtherClass继承。将继承公之于众,它会起作用。

答案 2 :(得分:1)

我认为扫描继承树不是一个好主意。看到这篇关于浏览vtable的帖子,它甚至看不到你的代码

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

我可以看到这在调试中很有用,但你不能在运行时依赖它。

我认为你遇到的是多重继承很复杂的原因,你有从多个基类继承的类,因此在这些情况下找到一个公共基类root来指向派生对象会变得毛茸茸。除了可能重新考虑你的遗产层次之外,我没有真正的答案。你可以使用组合而不是继承并坚持使用单个继承树吗?这会使事情变得更加简单。