在这个程序中:
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时,编译器会给出错误
error: cannot convert from base ‘Top’ to derived type ‘Left’ via virtual base ‘Top
即使在动态投射时,也会出现错误
error: cannot dynamic_cast ‘top1’ (of type ‘class Top*’) to type ‘class Left*’ (source type is not polymorphic)
因此,在Top类中添加虚拟析构函数时,它变为多态并且允许动态转换。
我无法理解为什么会发生这种情况。
答案 0 :(得分:2)
施法不能静态完成。想象一个几乎从Top(可能是多次)和Left继承的类。布局取决于该类的详细信息。因此,没有一种已知的方法可以计算出Left实例的数据所在的位置,仅给出Top实例的位置。
解决方案是将信息嵌入对象本身(通常作为vtable的一部分),然后动态地进行计算。所以你可能会包含一些数据,说“我真的是Left的一个实例,而我的Top基础实例是我的this指针指向的12个字节”。
但是C ++并不希望强制每个对象都拥有该信息,因为它通常不需要。它只需要通过多态类存储,这些类别(并不是巧合)正是需要有vtable的那些。