c – 为什么当涉及虚拟继承时,static_cast不能用于downcast?

考虑下面的代码:

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。从继承中删除虚拟使得代码有效。

这条规则存在的技术原因是什么?

技术问题是没有办法从Base *中解决在Base子对象的开始和Derived对象的开始之间的偏移。

在你的例子中,它看起来OK,因为只有一个类在一个Base基地,所以它似乎不相关的继承是虚拟的。但编译器不知道是否有人定义另一个类Derived2:public virtual Base,public Derived {},并且正在投射一个Base *指向它的Base子对象。通常[*],Derived2中的Base子对象和Derived子对象之间的偏移量可能与Base子对象与其最大派生类型为Derived的对象的完整Derived对象之间的偏移量不同,这正是因为Base是虚拟地继承。

所以没有办法知道完整对象的动态类型,以及你给出的指针和所需的结果之间的不同偏移,取决于动态类型。因此,演员是不可能的。

你的Base没有虚拟函数,因此没有RTTI,所以肯定没有办法告诉整个对象的类型。即使Base有RTTI(我不立即知道为什么),仍然禁止这个转换,但是我想没有在这种情况下检查一个dynamic_cast是可能的。

[*]我的意思是,如果这个例子不证明点,然后继续添加更多的虚拟继承,直到你发现一个情况下,偏移是不同的;-)

http://stackoverflow.com/questions/7484913/why-cant-static-cast-be-used-to-down-cast-when-virtual-inheritance-is-involved

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c – 为什么当涉及虚拟继承时,static_cast不能用于downcast?