考虑以下代码:
struct Base {};
struct Derived : public virtual Base {};
void f()
{
Base* b = new Derived;
Derived* d = static_cast<Derived*>(b);
}
这是标准禁止的([n3290: 5.2.9/2]
)所以代码无法编译,因为Derived
虚拟 继承自 Base
。从继承中删除 virtual
使代码有效。
此规则存在的技术原因是什么?
最佳答案
技术问题是无法解决 Base*
Base
开头之间的偏移量是多少子对象和 Derived
的开始目的。
在您的示例中,它看起来没问题,因为只看到一个带有 Base
的类基,因此继承是虚拟的似乎无关紧要。但是编译器不知道是否有人定义了另一个 class Derived2 : public virtual Base, public Derived {}
,并且正在转换 Base*
指着Base
那的子对象。通常[*],Base
之间的偏移量子对象和 Derived
Derived2
中的子对象可能与 Base
之间的偏移量不同子对象和完整的Derived
最派生类型为 Derived
的对象的对象,正是因为 Base
实际上是继承的。
所以没有办法知道完整对象的动态类型,以及你给出的转换指针和所需结果之间的不同偏移量,这取决于动态类型是什么。因此 Actor 阵容是不可能的。
您的Base
没有虚函数,因此没有 RTTI,所以肯定没有办法知道完整对象的类型。即使Base
, Actor 仍然被禁止确实有 RTTI(我不立即知道为什么),但我猜没有检查 dynamic_cast
在这种情况下是可能的。
[*] 我的意思是,如果这个例子不能证明这一点,那么继续添加更多的虚拟继承,直到你发现偏移量不同的情况;-)
关于c++ - 为什么涉及虚拟继承时不能使用static_cast进行向下转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7484913/