c++ - 多重虚继承情况下的casting

标签 c++ inheritance virtual

在这个程序中:

    class Top
    {
            public:
            int a;
    };

    class Left : virtual public Top
    {
            public:
            int b;
    };

    class Right : virtual public Top
    {
            public:
            int c;
    };

    class Bottom : public Left, public Right
    {
            public:
            int d;
    };

    class AnotherBottom : public Left, public Right
    {
            public:
            int e;
            int f;
    };

    int main()
    {
        Bottom* bottom1 = new Bottom();
        AnotherBottom* bottom2 = new AnotherBottom();
        Top* top1 = bottom1;
        Top* top2 = bottom2;
        Left* left = static_cast<Left*>(top1);
        return 0;
    }

我对这个程序几乎没有怀疑:

在执行 static_cast 时编译器给出错误

错误:无法通过虚基“Top”从基“Top”转换为派生类型“Left”

即使在动态转换中它也会给出错误

错误:无法 dynamic_cast ‘top1’(类型为‘class Top*’)以键入‘class Left*’(源类型不是多态的)

因此,在 Top 类中添加虚拟析构函数后,它就变成了多态的,并且允许动态转换。

我无法理解为什么会这样。

最佳答案

Actor 不能静态完成。想象一个从 Top(可能多次)和 Left 虚拟继承的类。布局取决于该类的详细信息。因此,没有单一的已知方法可以计算出 Left 实例的数据位置,仅给出 Top 实例的位置。

解决方案是将信息嵌入对象本身(通常作为 vtable 的一部分),然后动态地进行计算。所以你可能会包含一些数据说“我真的是 Left 的一个实例,我的 Top 基础实例距离我的 this 指针指向的地方有 12 个字节”。

但 C++ 不希望每个对象都被迫保存该信息,因为通常不需要它。它只需要由多态类存储,这些类(这不是巧合)正是那些无论如何都需要有一个 vtable 的类。

关于c++ - 多重虚继承情况下的casting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10567026/

相关文章:

c++ - C++ 中是否可以使用仅堆栈变​​量?

c++ - 特殊错误 - 参数尚不存在,直到参数名称更改然后它更有利地中断

c++ - 继承还是包容? C++

java - Java中的继承,访问子方法并使用父类数组

C++继承与抽象函数实现

c++ - 解决不可能重载无参数函数的方法

c++ - 如何声明一个类显式抽象?

C++类和对象——内存

c++ - 在 C 和 C++ 中请求内存缓存

java - 如何向 Jframe 添加抽象方法?