什么时候必须在C ++类中定义析构函数以及为什么?
刚开始在C ++中学习这一点并需要澄清。
答案 0 :(得分:5)
如果您的类需要进行特殊清理,例如释放动态分配的内存,则只需要定义析构函数。
答案 1 :(得分:3)
您需要在动态分配内存时定义析构函数。一个好的经验法则是,如果在任何构造函数中使用new,则可能需要析构函数。任何非自动存储或静态存储都被视为动态分配
任何属于清理类别的东西都适合放入析构函数,例如关闭网络连接
答案 2 :(得分:1)
可能还有其他原因,但我想到的第一个原因是你的某些类属性可能需要明确释放。
如果您的类只有两个int属性,那么当您调用delete myObject
时,这些属性将自动与您的对象一起删除。但如果它包含任何动态分配的属性,那么这些属性将不会与您的对象一起释放,因此您需要在析构函数中明确删除它们。
答案 3 :(得分:1)
如果析构函数的默认行为不是您想要的,则只需定义析构函数。
当一个对象被销毁时,析构函数会执行这些操作,无论您是否定义了自定义析构函数:
这实际上处理了您可能想要做的大多数事情。在构造函数中分配内存时,通常会定义自定义析构函数:
struct A {
B *b_ptr;
A() : b_ptr(new B) { }
~A() { delete b_ptr; }
};
但是当您使用标准容器和智能指针时,需要自定义析构函数的情况相对较少。例如,如果您有这样的类
struct A {
std::unique_ptr<B> b_ptr;
A() : b_ptr(new B) { }
};
不需要定义自己的析构函数,因为std :: unique_ptr将释放已分配的内存。同样,这里不需要定义析构函数
struct B {
ifstream input_stream;
B(const std::string &path) : input_stream(path) { }
};
因为在销毁input_stream成员时会自动关闭input_stream
。
有时,您需要做一些特别的事情。您需要特殊调用才能获取或释放资源。在这种情况下,你想要一个析构函数:
struct C {
ResourceHandle resource_handle;
C() : resource_handle(resouce_manager.acquireResource()) { }
~C() { resource_manager.releaseResource(resource_handle); }
};
但是,尽可能地,您希望本地化这种行为,以便它不必在许多类中重复。例如,您可能希望像这样创建类:
struct ResourceHolder {
ResourceHandle resource_handle;
ResourceHolder() : resource_handle(acquireResource()) { }
~ResourceHolder() { releaseResource(resource_handle); }
};
现在,您可以在每个需要其中一个资源的类中使用ResourceHolder,而且您再也不必重复获取和释放逻辑。
答案 4 :(得分:0)
析构函数不仅用于释放分配的内存,例如,在构造函数中。
您可以使用析构函数实现RAII-style功能。
利用此功能的类型示例:
std::fstream
关闭已打开的文件
std::lock_guard
解锁互斥锁
std::shared_ptr
会递减引用计数器或释放内存。
答案 5 :(得分:0)
您需要定义一个析构函数的实例: