假设我有ABC *类型的指针和另一个XYZ *类型的指针,它们都来自一个公共父类。
如果我通过显式地将XYZ *分配给ABC *,那么如果我调用
会发生什么删除abc; // abc的类型为XYZ *
我会得到任何例外或者它能正常工作吗?
我已经尝试了上面的代码并且它没有崩溃。那么有谁能告诉我在什么情况下会删除抛出异常/故障/崩溃等?
delet'ing指针崩溃程序的情况是什么?如果它们都定义了自定义析构函数,它们会崩溃吗
编辑:这是我的测试代码,没有任何崩溃
class ABC
{
public:
int a;
int b;
int c;
};
class XYZ
{
public:
double a;
double b;
double c;
};
int main()
{
ABC* abc = new ABC();
XYZ* xyz = (XYZ*)abc;
delete xyz;
return 0;
}
P.S:我在Windows平台上,如果有帮助的话。
EDIT2:好的,所以在阅读之后,我将问题改为,何时删除指针会导致崩溃(不包括未定义的行为)?
EDIT3:调用删除后会发生什么?会叫谁的析构函数?
答案 0 :(得分:5)
如果XYZ不是从ABC派生的,那么你就不应该将前者的对象转换为后者 - 无论你的删除是否有效都是无关紧要的。
答案 1 :(得分:5)
这是非法的。如果要在非数组删除表达式中删除的指针类型与要删除的对象的动态类型不同,则指向对象的类型必须是对象的基类已删除和基类必须具有虚拟析构函数。
见ISO / IEC 14882:2003 5.3.5 [expr.delete] / 2。
答案 2 :(得分:2)
您的代码将显示未定义的行为。请注意,这并不意味着它会崩溃,只是在您执行删除后它将处于未定义状态。 UB总是导致崩溃的想法(如果确实这样做会很好)是错误的。
答案 3 :(得分:0)
如果我通过显式地将XYZ *分配给ABC *
如果XYZ不是ABC的子类,则无论是通过reinterpret_cast
还是C风格的强制转换,这种显式强制转换都是未定义的行为。有时你会很幸运,即使它有不确定的行为,程序也能正常工作。不要算你的幸运星,也不要故意调用未定义的行为。