作者:淑香门蒂 | 来源:互联网 | 2022-12-06 11:50
首先要说我是西班牙语,我的英语非常糟糕,我使用了一名翻译,因为我看起来像个文盲而道歉:)
我已经多年没有玩c ++而且我已经忘记了很多,以至于我可能怀疑或者可能的失败是语言中的基本内容.
我编写了一个小代码来测试c ++中带有虚拟析构函数的delete运算符的开销,我发现只有在第一次调用delete时它才能正常工作.
代码就在这里(这是一个允许你在线编写代码并执行代码的页面,我在visual studio和gcc中进行了测试,它完全相同):https://onlinegdb.com/SkiI1dNDQ
有人能告诉我为什么会这样吗?只有第一次运作良好,第二次运行不顺利
我也把代码放在这里,结果给出了:
#include
class Base
{
public:
virtual ~Base() { printf("~Base\r\n"); }
void operator delete(void *m) { printf("delete Base\r\n"); }
};
class Derived : public Base
{
public:
Derived() { x = 1; }
~Derived() { printf("~Derived\r\n"); }
void operator delete(void *m) { printf("delete Derived\r\n"); }
int x;
};
int main()
{
Derived *derived = new Derived();
printf("1) delete derived (%i)\r\n", ((Derived*)derived)->x);
delete derived;
printf("2) delete derived (%i)\r\n", ((Derived*)derived)->x);
delete derived;
return 0;
}
结果:
1) delete derived (1)
~Derived
~Base
delete Derived
2) delete derived (1)
~Base
delete Base
现在,如果我们删除名为"Base"的"虚拟"类,一切都是完美的,逻辑上每当我们用"Derived"调用删除时(代码已准备好删除虚拟而没有任何失败).执行它:https://onlinegdb.com/SkXkgdVP7
谢谢
1> Jeremy Fries..:
Derived *derived = new Derived();
printf("1) delete derived (%i)\r\n", ((Derived*)derived)->x);
delete derived;
printf("2) delete derived (%i)\r\n", ((Derived*)derived)->x);
delete derived;
上面的代码不正确,并且正在调用未定义的行为.您只能删除一次对象; 您正在(尝试)两次删除同一个对象.问题是,在第一次调用delete之后,derived
现在是一个悬空指针(即它不再指向有效对象),尝试以任何方式取消引用它(包括调用delete
它)是错误的.