【C++知识杂记1】智能指针及其分类

智能指针(smart pointer) 是 C++11 引入的一类 模板类 ,用来封装原始指针,自动管理堆内存的生命周期,避免出现 内存泄漏悬空指针(野指针) 的问题。

当智能指针对象离开作用域时,它会自动调用 delete 来释放所管理的资源,从而实现 RAII(资源获取即初始化,Resource Acquisition Is Initialization) 思想。


🧠 智能指针的种类

C++ 标准库(<memory> 头文件)提供了三种主要的智能指针:


1. std::unique_ptr(独占智能指针)

  • 特点 :独占式所有权,一个资源只能由一个 unique_ptr 拥有。
  • 拷贝 :不允许拷贝,只能通过 std::move 转移所有权。
  • 适用场景:对象的生命周期和作用域绑定,保证同一时间只有一个所有者。
  • 创建方式 :推荐使用 std::make_unique<T>()(C++14 以后)。

示例:

cpp 复制代码
#include <memory>
#include <iostream>
using namespace std;

int main() {
    auto p = std::make_unique<int>(42);
    cout << *p << endl;  // 输出 42

    auto q = std::move(p); // 转移所有权
    if (!p) cout << "p is empty\n"; // p 已经不再管理对象
}

2. std::shared_ptr(共享智能指针)

  • 特点 :共享式所有权,多个 shared_ptr 可以指向同一资源。
  • 内存释放 :内部维护一个 引用计数 ,当最后一个 shared_ptr 被销毁时,才调用 delete 释放资源。
  • 适用场景:多个对象或函数需要共享同一个动态分配的对象。
  • 创建方式 :推荐使用 std::make_shared<T>()

示例:

cpp 复制代码
#include <memory>
#include <iostream>
using namespace std;

int main() {
    auto p1 = std::make_shared<int>(42);
    auto p2 = p1;  // 引用计数 +1

    cout << "use_count = " << p1.use_count() << endl; // 2

    p1.reset(); // p1 不再持有对象
    cout << "use_count = " << p2.use_count() << endl; // 1
}

⚠️ 注意:shared_ptr 可能导致 循环引用问题 (两个对象互相持有 shared_ptr,导致引用计数无法归零)。


3. std::weak_ptr(弱引用智能指针)

  • 特点 :一种 弱引用 ,用于配合 shared_ptr 使用,不增加引用计数。
  • 适用场景 :打破 shared_ptr 的循环引用。
  • 使用方式 :不能直接访问资源,必须先调用 .lock() 获得一个 shared_ptr

示例:

cpp 复制代码
#include <memory>
#include <iostream>
using namespace std;

int main() {
    auto sp = std::make_shared<int>(42);
    std::weak_ptr<int> wp = sp;  // 弱引用

    if (auto temp = wp.lock()) { // 转换为 shared_ptr
        cout << *temp << endl;   // 42
    }
}

📌 小结

智能指针 所有权 拷贝 释放时机 适用场景
unique_ptr 独占 ❌ 禁止拷贝,✔️ 允许 std::move 作用域结束时 对象唯一所有者
shared_ptr 共享 ✔️ 允许拷贝 引用计数归零时 多个对象共享同一资源
weak_ptr 无(弱引用) ✔️ 允许拷贝 不影响对象释放 辅助 shared_ptr,解决循环引用