C++智能指针是用于自动管理动态内存的工具,通过RAII(Resource Acquisition Is Initialization)机制确保资源在不再需要时被正确释放,从而避免内存泄漏。以下是C++中主要智能指针的详细介绍:
1. **std::unique_ptr
**
性能与选择建议
正确使用智能指针可显著提升代码安全性和可维护性,是现代C++资源管理的核心工具之一。
- 所有权模型:独占所有权,同一时间只能有一个
unique_ptr
指向某个对象。 - 特点:
- 不可复制,但可通过
std::move
转移所有权。 - 析构时自动释放所管理的对象。
- 支持自定义删除器(如
delete[]
)。
- 不可复制,但可通过
- 使用场景:
- 管理独占资源的生命周期(如工厂模式返回的对象)。
- 替代已废弃的
auto_ptr
。
- 示例:
#include <memory> auto ptr = std::make_unique<int>(42); // C++14起支持make_unique // 转移所有权 std::unique_ptr<int> ptr2 = std::move(ptr);
2. **
std::shared_ptr
** - 所有权模型:共享所有权,多个
shared_ptr
可指向同一对象,通过引用计数管理生命周期。 - 特点:
- 引用计数为0时自动释放对象。
- 支持自定义删除器。
- 使用
std::make_shared
可合并内存分配(对象和控制块),提升性能。
- 潜在问题:
- 循环引用:两个
shared_ptr
互相指向对方,导致内存泄漏(需用weak_ptr
解决)。
- 循环引用:两个
- 示例:
auto shared1 = std::make_shared<int>(42); std::shared_ptr<int> shared2 = shared1; // 引用计数+1
3. **
std::weak_ptr
** - 作用:解决
shared_ptr
的循环引用问题,作为弱引用不增加引用计数。 - 特点:
- 需通过
lock()
方法获取临时shared_ptr
访问对象。 - 不管理对象生命周期,仅观察资源是否存在。
- 需通过
- 使用场景:
- 缓存、观察者模式、打破循环引用。
- 示例:
std::weak_ptr<int> weak = shared1; if (auto temp = weak.lock()) { // 检查对象是否存活 // 使用temp访问资源 }
5. 自定义删除器
- 用途:处理特殊资源释放(如文件句柄、数组)。
- 示例:
// unique_ptr自定义删除器 std::unique_ptr<int, void(*)(int*)> ptr(new int[5], [](int* p) { delete[] p; }); // shared_ptr自定义删除器 std::shared_ptr<int> arr(new int[5], [](int* p) { delete[] p; });
使用注意事项
- 避免裸指针混用:不要将同一裸指针交给多个智能指针管理。
- 优先使用
make_shared
和make_unique
:提升性能并避免显式new
。 - 循环引用:使用
weak_ptr
打破循环。 - 线程安全:
shared_ptr
引用计数操作是原子的,但对象访问需额外同步。- 多线程中修改同一
shared_ptr
实例需加锁。
- **
unique_ptr
**:轻量级,无额外开销,适合独占资源。 - **
shared_ptr
**:引用计数有少量开销,适合共享资源。 - **
weak_ptr
**:配合shared_ptr
使用,避免循环引用。