假设我们有以下课程层级:
class B{
B() { cout<<"B\n"; }
~B(){ cout<<"~B\n"; }
};
class D1 : virtual public B {
D1() { cout<<"D1\n"; }
~D1(){ cout<<"~D1\n"; }
};
class D2 : virtual public B {
D2() { cout<<"D2\n"; }
~D2(){ cout<<"~D2\n"; }
};
class MM : public D1, public D2 {
MM() { cout<<"MM\n"; }
~MM(){ cout<<"~MM\n"; }
};
int main(){
B *p = new MM();
D1 *p2 = dynamic_cast<D1*>(p);
D2 *p3 = dynamic_cast<D2*>(p);
MM *p4 = dynamic_cast<MM*>(p);
//delete p4;
//delete p3;
delete p2;
delete p;
return 0;
}
我不习惯使用dynamic_cast和从基类到派生类的指针,所以如果我错了,请纠正我,但这基本上会创建一个类型为B *的指针给MM()类型的对象。在此之后它创建另外两个指针,并使用dynamic_cast将B *指针强制转换为D *,D2 *和MM *。
现在令我担心的是:全部四个指向同一块内存(对吗?)。当我们删除p2,然后删除p时,它可以正常工作。如果我们取消注释“删除p3”或删除“p4”,程序会崩溃,我不知道为什么。我还注意到,如果我们取消注释前面提到的任何删除语句并注释“删除p2”,代码工作正常。
有人可以解释一下吗?谢谢!
PS:你们是否会如此善良地解释一旦我们创建了另一个指针并使用前一个与dynamic_cast一起投射分配的内存会发生什么?谢谢!
答案 0 :(得分:3)
通过其他类型删除类(没有虚拟析构函数)是未定义的行为(UB)。
两次删除指针也是未定义的行为(UB)。
因此,您的代码似乎可以正常工作,但它也无效。