【c++】析构函数
【c++】析构函数
1.命名规则:类名前加波浪号 ~
,且无参数、无返回值。
class MyClass {
public:
~MyClass(); // 析构函数声明
};
MyClass::~MyClass() { /* 释放资源 */ } // 类外定义
析构函数的核心作用
- 释放资源:在对象生命周期结束时自动调用,用于释放对象占用的资源(如动态内存、文件句柄、网络连接等)。
能否重载:
析构函数不能重载,一个类有且仅有一个析构函数
默认析构函数
- 自动生成:若未显式定义析构函数,编译器会生成一个默认析构函数。
- 行为限制:
- 默认析构函数仅释放对象自身内存,不会处理动态分配的资源(如
new
分配的堆内存)。
- 默认析构函数仅释放对象自身内存,不会处理动态分配的资源(如
何时需要自定义析构函数?
- 资源管理:类持有手动分配的资源(如
new
/malloc
、文件句柄)时,需显式释放。class ResourceHolder { private: int* data; public: ResourceHolder(int size) { data = new int[size]; } ~ResourceHolder() { delete[] data; } // 必须自定义析构函数 };
析构函数的调用时机
- 局部对象:离开作用域时。
{ MyClass obj; // 构造函数调用 } // 离开作用域时析构函数自动调用
- 动态对象:通过
delete
释放时。MyClass* ptr = new MyClass(); delete ptr; // 析构函数调用
- 容器元素:容器(如
std::vector
)销毁时,所有元素的析构函数被调用。
显式调用析构函数(不推荐)
- 语法允许但风险高:可通过对象或指针直接调用析构函数,但需确保:
- 不重复释放:避免多次调用导致未定义行为。
- 手动管理内存:显式调用后需手动释放对象内存(如
operator delete
)。
MyClass obj; obj.~MyClass(); // 显式调用(危险!后续操作可能导致崩溃)
总结对比
特性 | 析构函数 |
---|---|
命名 | ~类名() |
数量 | 唯一,不可重载 |
调用时机 | 对象销毁时自动调用 |
默认行为 | 释放对象内存,递归调用成员析构函数 |
自定义必要性 | 需管理动态资源时 |
虚析构函数 | 多态基类必须声明 |
显式调用风险 | 需手动管理内存,易导致重复释放 |
常见错误
未释放动态内存:
class LeakDemo {
private:
int* buffer;
public:
LeakDemo(int size) { buffer = new int[size]; }
// 未定义析构函数!导致内存泄漏
};