【发布时间】:2012-01-23 20:42:43
【问题描述】:
以下代码在 g++ 4.6.1 上编译失败:
template<class Base>
struct GetBase {
Base * getBase() {
return static_cast<Base *>(this);
}
};
template<class Derived>
struct Parent : private GetBase<Derived> {
using GetBase<Derived>::getBase;
int y() {
return getBase()->x();
}
};
struct Child : public Parent<Child> {
int x() {
return 5;
}
int z() {
return y();
}
};
有错误
In member function ‘Base* GetBase<Base>::getBase() [with Base = Child]’:
instantiated from ‘int Parent<Derived>::y() [with Derived = Child]’
instantiated from here
error: ‘GetBase<Child>’ is an inaccessible base of ‘Child’
将 static_cast 更改为 reinterpret_cast 将使代码能够编译,并且在这种情况下可以正常工作,但我想知道这是否在所有情况下都是可接受的解决方案?即,指向基类的指针是否与此不同?我假设如果父母有数据成员,这可能会发生多重继承?如果GetBase是第一个超类,是否保证this指针相等?
【问题讨论】:
-
我很震惊这个在 VS2010 上的编译......不管你应该重构你的设计。
-
是的,在某些情况下 reinterpret_cast 会中断,其中大部分是完全由实现定义的。
-
至少考虑删除
getBase()的无限层,并更喜欢dynamic_cast来确定派生自基类指针。 -
仅供参考的虚拟方法可能会简化这种疯狂的继承方案。
-
@AJG85- 这个设置(CRTP)的重点是避免动态多态性并在编译时处理所有事情。添加虚拟方法和
dynamic_cast会破坏设计的目的。