C++中智能指针如何设计和使用


在C++中,智能指针是一种用于自动管理动态分配的内存的模板类。它们通过封装裸指针(raw pointer)并提供一个自动化的方式来释放其所指向的对象,从而帮助避免内存泄漏。C++标准库提供了几种智能指针,包括`std::unique_ptr`、`std::shared_ptr`和`std::weak_ptr`。下面将分别介绍这些智能指针的设计和使用方法。

### 1. std::unique_ptr

`std::unique_ptr`表示对对象的独占所有权。在同一时间内,只能有一个`std::unique_ptr`指向一个给定对象(通过禁止拷贝构造函数和拷贝赋值操作符,只提供移动语义)。

**设计特点**:

- 独占所有权

- 不可拷贝,但可移动

- 当`std::unique_ptr`被销毁时,其所指向的对象也会被自动删除

**使用示例**:


#include <memory>
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass created\n"; }
    ~MyClass() { std::cout << "MyClass destroyed\n"; }
    void doSomething() { std::cout << "Doing something\n"; }
};

int main() {
    std::unique_ptr<MyClass> ptr(new MyClass()); // 创建并管理MyClass对象
    ptr->doSomething(); // 调用成员函数
    // 当ptr离开作用域时,MyClass对象被自动删除
    return 0;
}

### 2. std::shared_ptr

`std::shared_ptr`表示对对象的共享所有权。多个`std::shared_ptr`可以指向同一个对象,对象会在最后一个指向它的`std::shared_ptr`被销毁时被删除。

**设计特点**:

- 共享所有权

- 可拷贝,可移动

- 使用控制块(control block)来跟踪有多少`std::shared_ptr`实例共享同一个对象

**使用示例**:


#include <memory>
#include <iostream>

class MyClass { /* 同上 */ };

int main() {
    std::shared_ptr<MyClass> ptr1(new MyClass());
    std::shared_ptr<MyClass> ptr2 = ptr1; // ptr1和ptr2共享所有权

    // 当ptr1和ptr2都离开作用域时,MyClass对象被删除
    return 0;
}

### 3. std::weak_ptr

`std::weak_ptr`是一种不拥有其所指对象的智能指针,它被用来解决`std::shared_ptr`可能引起的循环引用问题。`std::weak_ptr`必须和一个`std::shared_ptr`实例一起工作,它不能单独存在。

**设计特点**:

- 不拥有对象的所有权

- 用来解决`std::shared_ptr`的循环引用问题

- 需要与`std::shared_ptr`配合使用

**使用示例**:


#include <memory>
#include <iostream>

class MyClass { /* 同上 */ };

int main() {
    std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();
    std::weak_ptr<MyClass> weakPtr = ptr;

    if (auto locked = weakPtr.lock()) { // 尝试获取一个shared_ptr
        locked->doSomething();
    }

    // 当ptr离开作用域时,MyClass对象被删除
    // weakPtr不再指向有效对象
    return 0;
}

这些智能指针的设计和使用方法帮助C++程序员更轻松地管理动态分配的内存,减少内存泄漏的风险。