C++中的智能指针是基于**RAII(Resource Acquisition Is Initialization)**理念设计的自动化内存管理工具,通过对象生命周期管理资源。以下是三种核心智能指针的工作原理:
1. std::unique_ptr(独占所有权)
-
核心机制:通过移动语义(Move Semantics)确保资源仅有一个所有者。
-
所有权转移 :
cppstd::unique_ptr<int> ptr1 = std::make_unique<int>(10); std::unique_ptr<int> ptr2 = std::move(ptr1); // ptr1 释放所有权 -
资源释放 :当
unique_ptr离开作用域时,自动调用析构函数并释放内存。
2. std::shared_ptr(共享所有权)
-
引用计数 :
- 每个
shared_ptr内部维护一个控制块(包含引用计数器和弱计数器)。 - 复制时引用计数递增:$$ \text{ref_count} \leftarrow \text{ref_count} + 1 $$
- 析构时递减:$$ \text{ref_count} \leftarrow \text{ref_count} - 1 $$
- 当$$ \text{ref_count} = 0 $$时释放资源。
- 每个
-
示例 :
cppauto p1 = std::make_shared<int>(20); // 引用计数=1 { auto p2 = p1; // 引用计数=2 } // p2析构,引用计数=1 ``` // p1析构,引用计数=0,释放内存
3. std::weak_ptr(观察所有权)
-
解决循环引用 :不增加引用计数,需通过
lock()转为shared_ptr访问资源:cppstd::weak_ptr<int> w_ptr; { auto s_ptr = std::make_shared<int>(30); w_ptr = s_ptr; // 不增加引用计数 } if (auto tmp = w_ptr.lock()) { // 资源已释放,tmp为空 // 操作资源 }点击并拖拽以移动
关键操作对比
| 操作 | unique_ptr |
shared_ptr |
weak_ptr |
|---|---|---|---|
| 所有权独占 | ✓ | ✗ | ✗ |
| 允许多引用 | ✗ | ✓ | ✗ |
| 可直接访问资源 | ✓ | ✓ | ✗¹ |
| 自动释放(零引用) | ✓ | ✓ | ✗ |
¹需通过
lock()转为shared_ptr后访问
应用场景
unique_ptr:工厂模式返回对象、独占资源管理。shared_ptr+weak_ptr:缓存系统、观察者模式。- 避免使用
auto_ptr(C++17废弃,所有权转移不安全)。
智能指针通过自动化生命周期管理,显著降低了内存泄漏和悬垂指针的风险。