在 C++ 中,智能指针是用于自动管理动态内存的工具,可以避免内存泄漏和悬空指针等问题。
C++11 引入了三种主要的智能指针:std::unique_ptr
、std::shared_ptr
和 std::weak_ptr
。
以下是它们的使用场景和特点:
1. std::unique_ptr
- 特点:
- 独占所有权:同一时间只能有一个
unique_ptr
指向某个对象。 - 不能复制,只能移动(通过
std::move
)。 - 轻量级,性能开销小。
- 独占所有权:同一时间只能有一个
- 使用场景:
- 管理独占资源的生命周期(如动态数组、文件句柄等)。
- 需要明确资源所有权的场景。
- 示例:
#include <memory> #include <iostream> int main() { std::unique_ptr<int> ptr = std::make_unique<int>(10); // 创建 unique_ptr std::cout << *ptr << std::endl; // 输出 10 // std::unique_ptr<int> ptr2 = ptr; // 错误:不能复制 std::unique_ptr<int> ptr2 = std::move(ptr); // 正确:移动语义 if (!ptr) { std::cout << "ptr is now null" << std::endl; } return 0; }
2. std::shared_ptr
- 特点:
- 共享所有权:多个
shared_ptr
可以指向同一个对象。 - 使用引用计数管理资源生命周期,当引用计数为 0 时自动释放资源。
- 支持复制和移动。
- 性能开销较大(需要维护引用计数)。
- 共享所有权:多个
- 使用场景:
- 多个对象共享同一资源的场景。
- 需要共享所有权的复杂数据结构(如图、树等)。
- 示例:
#include <memory> #include <iostream> int main() { std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // 创建 shared_ptr std::shared_ptr<int> ptr2 = ptr1; // 复制 shared_ptr std::cout << *ptr1 << " " << *ptr2 << std::endl; // 输出 10 10 std::cout << ptr1.use_count() << std::endl; // 输出 2(引用计数) return 0; }
3. std::weak_ptr
- 特点:
- 弱引用:不增加引用计数,不影响资源的生命周期。
- 需要与
shared_ptr
配合使用。 - 用于解决
shared_ptr
的循环引用问题。
- 使用场景:
- 解决
shared_ptr
的循环引用问题(如双向链表、观察者模式等)。 - 需要观察资源但不影响其生命周期的场景。
- 解决
- 示例:
#include <memory> #include <iostream> int main() { std::shared_ptr<int> sharedPtr = std::make_shared<int>(10); std::weak_ptr<int> weakPtr = sharedPtr; // 创建 weak_ptr if (auto lockedPtr = weakPtr.lock()) { // 尝试提升为 shared_ptr std::cout << *lockedPtr << std::endl; // 输出 10 } else { std::cout << "Resource is no longer available" << std::endl; } sharedPtr.reset(); // 释放资源 if (weakPtr.expired()) { // 检查资源是否已释放 std::cout << "Resource is expired" << std::endl; } return 0; }
4. 三种智能指针的对比
特性 | std::unique_ptr | std::shared_ptr | std::weak_ptr |
---|---|---|---|
所有权 | 独占 | 共享 | 无所有权(弱引用) |
复制 | 不支持 | 支持 | 支持 |
移动 | 支持 | 支持 | 支持 |
引用计数 | 无 | 有 | 无 |
性能开销 | 低 | 高 | 低 |
使用场景 | 独占资源 | 共享资源 | 解决循环引用或观察资源 |
5. 总结
std::unique_ptr
:适用于独占资源的场景,性能开销小。std::shared_ptr
:适用于共享资源的场景,支持引用计数。std::weak_ptr
:适用于解决循环引用或观察资源的场景,不增加引用计数。
合理选择智能指针可以显著提高代码的安全性和可维护性,避免内存泄漏和悬空指针等问题。
THE END
暂无评论内容