# 析构函数

URL: https://caijiao.org/cpp/oop/destructors
Source: docs/cpp/oop/destructors.md
Description: 本节介绍 C++ 中的析构函数，讲解析构函数的作用、定义与使用。析构函数是用于清理对象所占用资源的特殊成员函数，了解析构函数有助于管理动态分配的内存和其他资源。

析构函数是 C++ 中用于对象销毁时进行清理操作的特殊成员函数。当对象的生命周期结束时，析构函数会自动被调用。它的主要作用是释放对象所占用的资源，如动态分配的内存、打开的文件句柄等。析构函数的名称与类名相同，但前面有一个波浪号（`~`）。

## 析构函数的定义

析构函数的名称必须与类名相同，并且必须以 `~` 开头。析构函数不带任何参数，也没有返回值。析构函数会在对象生命周期结束时自动调用。

### 示例：析构函数的定义与使用

```cpp
#include <iostream>
using namespace std;

class Person {
public:
    string name;
    int* age;

    // 构造函数
    Person(string n, int a) {
        name = n;
        age = new int(a); // 动态分配内存
        cout << "Person " << name << " is created." << endl;
    }

    // 析构函数
    ~Person() {
        delete age; // 释放动态分配的内存
        cout << "Person " << name << " is destroyed." << endl;
    }

    void introduce() {
        cout << "Hello, my name is " << name << " and I am " << *age << " years old." << endl;
    }
};

int main() {
    Person person1("Alice", 25);
    person1.introduce();

    return 0;
}
````

### 输出：

```
Person Alice is created.
Hello, my name is Alice and I am 25 years old.
Person Alice is destroyed.
```

在上述代码中，`Person` 类的构造函数为 `age` 分配了动态内存，而析构函数负责释放这块内存。通过析构函数，确保了在对象销毁时没有内存泄漏。

## 析构函数的作用

析构函数的主要作用是：

1. **释放动态内存**：如果类中使用了 `new` 或其他动态内存分配方法，析构函数应负责释放这些内存。
2. **清理资源**：除了内存外，析构函数还可以关闭打开的文件、释放数据库连接等。
3. **防止资源泄漏**：确保在对象销毁时，所有的资源都得以释放，避免资源泄漏。

## 析构函数的特点

* **自动调用**：析构函数在对象生命周期结束时自动调用，无需手动调用。
* **没有返回值和参数**：析构函数不能有返回值，也不能带有参数。
* **每个类只能有一个析构函数**：一个类只能定义一个析构函数。

## 虚析构函数

如果类具有派生类，并且派生类通过基类指针或引用访问对象时，为确保派生类的析构函数能够正确执行，基类的析构函数应声明为虚函数。这样，C++ 会确保在删除基类指针时，正确调用派生类的析构函数。

### 示例：虚析构函数

```cpp
#include <iostream>
using namespace std;

class Base {
public:
    virtual ~Base() {
        cout << "Base Destructor" << endl;
    }
};

class Derived : public Base {
public:
    ~Derived() {
        cout << "Derived Destructor" << endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    delete basePtr; // 虚析构函数确保调用派生类析构函数
    return 0;
}
```

### 输出：

```
Derived Destructor
Base Destructor
```

在这个例子中，`Base` 类的析构函数被声明为虚函数，因此当 `basePtr` 被删除时，派生类 `Derived` 的析构函数首先被调用，然后才调用基类的析构函数。没有虚析构函数时，基类的析构函数可能不会正确调用，导致资源泄漏。

## 小结

* 析构函数是 C++ 中用于在对象生命周期结束时清理资源的特殊成员函数。
* 析构函数没有参数和返回值，它在对象销毁时自动被调用。
* 析构函数通常用于释放动态分配的内存和清理其他资源，防止资源泄漏。
* 如果类有继承关系，并且通过基类指针删除派生类对象，应将析构函数声明为虚函数。

析构函数是面向对象编程中不可或缺的一部分，合理使用析构函数可以有效管理资源，确保程序的稳定性和性能。
