c++ - 为什么涉及虚拟继承时不能使用static_cast进行向下转换?

标签 c++ virtual-inheritance downcast static-cast

考虑以下代码:

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/

相关文章:

c++ - 使用 `static_cast` 向下转换空指针(单继承或多继承)

c# - 如何强制对泛型进行 downcast

uiimage - 从 AnyObject 向下转换为 UIImage[] - Swift

c++ - 虚拟继承

c++ - 术语不计算为采用 1 个参数的函数

c++ - sizeof() : the size of a class isn't the same as the size of it's members together?

c++ - 将自定义 QItemDelegate 与 QSortFilterProxyModel 结合使用

c++ - 为什么孙类的父类不处理祖类的初始化?

c++ - 虚拟类继承对象大小问题

c++ - 如何检索 Windows XP 中的所有事件日志?