在什么情况下,都不会调用c++析构函数
In what kind of situation, c++ destructor will not be called?
在c++中,我们喜欢在析构函数中做一些事情。但在什么情况下,析构函数不会被调用?
以下情况下的示例:
- 线程中的
exit()
调用 - 未处理的异常和退出
TerminateProcess()
(在Windows中)- 热/冷重新启动计算机
- 计算机突然断电
这是每个C++程序员都应该知道的一种情况:
#include <stdio.h>
class EmbeddedObject {
private:
char *pBytes;
public:
EmbeddedObject() {
pBytes = new char[1000];
}
~EmbeddedObject() {
printf("EmbeddedObject::~EmbeddedObject()n");
delete [] pBytes;
}
};
class Base {
public:
~Base(){
printf("Base::~Base()n");
}
};
class Derived : public Base {
private:
EmbeddedObject emb;
public:
~Derived() {
printf("Derived::~Derived()n");
}
};
int main (int argc, const char * argv[])
{
Derived *pd = new Derived();
// later for some good reason, point to it using Base pointer
Base* pb = pd;
delete pb;
}
CCD_ 3将被调用,但CCD_。这意味着~Derived()
中的代码不执行。它可能必须做一些重要的事情。此外,它的EmbeddedObject
的析构函数本应被自动调用,但没有被调用。因此,EmbeddedObject
没有机会释放其动态分配的数据。这会导致内存泄漏。
解决方案,使类Base
中的析构函数virtual
:
class Base {
public:
virtual ~Base() {
}
};
对上述程序进行这一次更改意味着所有析构函数都将按以下顺序调用:Derived::~Derived()
、EmbeddedObject::~EmbeddedObject()
、Base::~Base()
阅读有关析构函数的一般信息。这类问题比你提到的其他情况更可能引起你的关注。例如,在断电的情况下,所有安全清理的赌注通常都会被取消!
在C++中,我们可以很好地控制按照我们希望的顺序强制调用析构函数,这是个好消息。然而,在你编写的程序中,如果你不够小心,你的对象可能会被泄露,根本不会被删除。
如果创建了一个新放置的对象,则不会自动调用该对象的析构函数。
从所提到的显而易见的事情开始,即exit()、终止信号、电源故障等。
有一些非常常见的编程错误会阻止析构函数被调用。
1) 使用创建对象的动态阵列object* x = new object[n]
,但用delete x
而不是delete[] x;
释放
2) 不是在对象上调用delete(),而是调用free()。当内存通常被释放时,析构函数将不会被调用。
3) 假设您有一个对象层次结构,它本应声明虚拟析构函数,但由于某种原因没有。如果其中一个子类实例在继承结构中被强制转换为不同的类型,然后被删除,它可能不会调用所有的析构函数。
在另一个因抛出异常而被调用的析构函数中抛出异常。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- std::cout.imbue()多重调用
- 函数何时会在c++中包含stack_Unwind_Resume调用