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转换SomeOtherClassdynamic_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

我认为扫描你的继承树不是一个好主意。请参阅这篇关于通过 vtables 的帖子,它甚至看起来都无法通过您的代码访问

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

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

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

于 2012-04-30T19:41:33.947 回答
1

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

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

我需要在树中搜索从 Able 继承的位置。

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

- 编辑 -

您使用私有继承从 SomeOtherClass 继承。公开继承,它会起作用。

于 2012-04-30T19:31:40.007 回答