我有一个模板,它为类增加了一个特定的能力:
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’
任何想法为什么?
答案 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来指向派生对象会变得毛茸茸。除了可能重新考虑你的遗产层次之外,我没有真正的答案。你可以使用组合而不是继承并坚持使用单个继承树吗?这会使事情变得更加简单。