C++智能指针是用于自动管理动态内存的工具,位于头文件 <memory> 中,核心作用是自动管理动态分配的内存,防止内存泄漏,并明确资源所有权关系。以下是三类核心智能指针及其用法:
1. unique_ptr(独占所有权)
- 特点:同一时间只能有一个
unique_ptr指向对象,禁止拷贝(允许移动)。 - 适用场景:独占资源所有权,如工厂模式返回对象、管理数组。
- 示例:
#include <memory> // 创建 unique_ptr std::unique_ptr<int> u1(new int(10)); auto u2 = std::make_unique<int>(20); // C++14 更安全 // 移动所有权 std::unique_ptr<int> u3 = std::move(u1); // u1 变为 nullptr // 自定义删除器(例如用于文件句柄) auto file_deleter = [](FILE* fp) { if (fp) fclose(fp); }; std::unique_ptr<FILE, decltype(file_deleter)> file_ptr(fopen("test.txt", "r"), file_deleter);
2. shared_ptr(共享所有权)
- 特点:通过引用计数管理对象,计数归零时自动释放资源。
- 注意:循环引用会导致内存泄漏(需配合
weak_ptr解决)。 - 示例:
struct Node { std::shared_ptr<Node> next; // std::weak_ptr<Node> next; // 若存在循环引用,改用 weak_ptr }; auto node1 = std::make_shared<Node>(); auto node2 = std::make_shared<Node>(); node1->next = node2; node2->next = node1; // 循环引用!计数永不归零 // 共享所有权:多个指针指向同一对象 std::shared_ptr<int> s1 = std::make_shared<int>(30); std::shared_ptr<int> s2 = s1; // 引用计数 +1
3. weak_ptr(弱引用)
- 特点:不增加引用计数,用于解决
shared_ptr循环引用问题。 - 用法:需通过
lock()转换为shared_ptr以访问资源。 - 示例:
struct SafeNode { std::weak_ptr<SafeNode> next; // 避免循环引用 }; auto node1 = std::make_shared<SafeNode>(); auto node2 = std::make_shared<SafeNode>(); node1->next = node2; node2->next = node1; // 无循环引用,计数正常归零 // 访问 weak_ptr 指向的对象 if (auto spt = node1->next.lock()) { // 检查对象是否存活 *spt; // 安全使用资源 }
关键对比表
| 特性 | unique_ptr | shared_ptr | weak_ptr |
|---|---|---|---|
| 所有权模型 | 独占 | 共享 | 无所有权(弱引用) |
| 拷贝操作 | ❌ 禁止 | ✅ 增加计数 | ✅ 不影响计数 |
| 移动操作 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
| 开销 | 几乎无额外开销 | 引用计数开销(原子操作) | 引用计数开销 |
| 适用场景 | 单一所有者 | 多个所有者 | 打破循环引用 |
最佳实践
- 优先使用
make_unique/make_shared:auto ptr = std::make_unique<int>(42); // 避免显式 new,更安全高效 auto sptr = std::make_shared<int>(42); // 单次内存分配(对象+计数) - 避免裸指针与智能指针混用:
int* raw = new int(10); std::unique_ptr<int> uptr(raw); // 正确 // std::unique_ptr<int> uptr2(raw); // 错误!多个独占指针管理同一资源 - 传递智能指针:
- 函数内不保留所有权 → 传引用或原始指针(
T*)。 - 转移所有权 → 传
unique_ptr的右值引用。 - 共享所有权 → 传
shared_ptr(值传递以增加计数)。
- 函数内不保留所有权 → 传引用或原始指针(
与传统指针的对比
| 特性 | 原始指针 | 智能指针 |
|---|---|---|
| 内存释放 | 手动delete | 自动释放 |
| 所有权语义 | 不明确 | 通过类型明确(独占/共享) |
| 异常安全 | 需额外处理 | 默认保证 |
| 循环引用 | 可能泄漏 | weak_ptr可解 |
| 线程安全 | 完全无保护 | shared_ptr引用计数原子操作 |
总结:智能指针的核心价值是通过自动化资源管理+明确所有权模型,将开发者的精力从内存管理中解放出来,显著提升代码健壮性。据统计,合理使用智能指针可减少70%以上的内存泄漏问题,是现代C++资源管理的基石。

990

被折叠的 条评论
为什么被折叠?



