如何手动销毁 指针、变量和类数组?

1. 引用(Reference):无法手动销毁

⚠️ 引用本身无法手动销毁!因为:

  • 引用只是别名
  • 生命周期跟随被引用对象
  • 不能重新绑定到其他对象

2. 指针(Pointer)->delete

2.1 单个对象指针

1
2
3
4
// 动态分配的单个对象
MyClass* ptr = new MyClass();
delete ptr; // ✅ 销毁对象
ptr = nullptr; // ✅ 好习惯:置空指针

2.2 数组指针

1
2
3
4
// 动态分配的数组
MyClass* arrPtr = new MyClass[5];
delete[] arrPtr; // ✅ 注意用delete[]
arrPtr = nullptr;

2.3 智能指针(推荐),自动销毁

1
2
3
4
5
6
7
8
9
#include <memory>

// unique_ptr自动管理生命周期
std::unique_ptr<MyClass> smart_ptr(new MyClass());
// 离开作用域自动销毁

// shared_ptr引用计数
std::shared_ptr<MyClass> shared_ptr = std::make_shared<MyClass>();
// 当引用计数为0时自动销毁

3. 普通变量!!:无法手动销毁

  • 自动变量(栈上)会自动销毁
  • 不需要也不能手动销毁
1
2
3
4
void func() {
int x = 10; // 离开作用域自动销毁
MyClass obj; // 离开作用域自动调用析构函数
} // 自动清理

4. 类数组

4.1 栈上的类数组

1
2
3
{
MyClass arr[5]; // 栈上分配
} // 自动调用每个元素的析构函数

4.2 堆上的类数组

1
2
3
4
5
6
// 动态分配的类数组
MyClass* arr = new MyClass[5];

// 销毁
delete[] arr; // ✅ 必须用delete[],会调用每个元素的析构函数
arr = nullptr;

5. 实际例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Resource {
public:
Resource() { std::cout << "Constructor\n"; }
~Resource() { std::cout << "Destructor\n"; }
};

void example() {
// 1. 动态单个对象
Resource* p1 = new Resource();
delete p1;
p1 = nullptr;

// 2. 动态数组
Resource* p2 = new Resource[3];
delete[] p2;
p2 = nullptr;

// 3. 智能指针
{
auto sp = std::make_unique<Resource>();
} // 自动销毁

// 4. 栈对象
{
Resource r;
} // 自动销毁
}

⚠️ 注意事项

  1. 避免内存泄漏

    1
    2
    3
    4
    void bad() {
    MyClass* p = new MyClass();
    // ❌ 忘记delete
    } // 内存泄漏!
  2. 避免重复删除

    1
    2
    3
    MyClass* p = new MyClass();
    delete p;
    delete p; // ❌ 重复删除,未定义行为
  3. **数组删除要用 delete[]**:

    1
    2
    3
    MyClass* arr = new MyClass[5];
    delete arr; // ❌ 错误:应该用delete[]
    delete[] arr; // ✅ 正确
  4. 智能指针优先

    1
    2
    3
    4
    // ✅ 推荐:使用智能指针
    std::unique_ptr<MyClass> ptr(new MyClass());
    // 或更好
    auto ptr = std::make_unique<MyClass>();

💡 最佳实践

  1. 优先使用栈对象

    1
    2
    3
    void func() {
    MyClass obj; // ✅ 自动管理生命周期
    }
  2. 必要时使用智能指针

    1
    2
    auto ptr = std::make_unique<MyClass>();
    auto shared = std::make_shared<MyClass>();
  3. 避免裸指针

    1
    2
    3
    4
    5
    // ❌ 避免
    MyClass* ptr = new MyClass();

    // ✅ 使用
    std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>();
  4. 资源获取即初始化(RAII)

    1
    2
    3
    4
    5
    6
    class RAIIWrapper {
    Resource* ptr;
    public:
    RAIIWrapper() : ptr(new Resource()) {}
    ~RAIIWrapper() { delete ptr; }
    };
  5. 清理后置空

    1
    2
    3
    MyClass* ptr = new MyClass();
    delete ptr;
    ptr = nullptr; // ✅ 好习惯

需要我详细解释任何部分吗?比如 RAII 模式或智能指针的具体使用?