10 智能指针
智能指针
内存泄漏分析工具:valgrind
std::unique_ptr
std::unique_ptr
是C++11标准引入的智能指针之一,用于独占式管理单个动态分配的对象。它提供了自动内存管理的功能,确保当unique_ptr
离开作用域时,它所管理的对象会被自动销毁,符合==RAII原则==
特性
- 独占所有权:
std::unique_ptr
拥有其指向的对象的独占所有权。这意味着在任何给定时间,只有一个unique_ptr
可以管理一个给定的动态分配对象 - 不可复制:为了防止所有权的歧义,
std::unique_ptr
不支持拷贝操作。这避免了多个指针指向同一资源时可能出现的资源管理问题 - 可移动:
std::unique_ptr
支持移动语义,这意味着你可以将一个unique_ptr
的所有权转移给另一个unique_ptr
。移动后,原始的unique_ptr
将不再拥有任何对象 - 析构时自动释放资源:当
unique_ptr
的实例被销毁时,它会自动释放所管理的资源(即删除它所指向的对象) - 自定义删除器:
std::unique_ptr
允许你指定一个自定义的删除器,这可以用来管理非默认的资源释放逻辑 - 该类重载了=操作符,如果对于一个
std::unique_ptr
重新赋值,那么先前分配的资源会被直接释放 - 该类由于独占性,所以一般不当函数的形参,除非使用移动语义来转移资源的所有权
语法
管理单个对象:
1 | void function() |
管理数组:
1 | { |
std::shared_ptr
该智能指针用于管理动态分配的内存,并且允许多个
shared_ptr
实例共享对同一资源的所有权
特性
- 共享所有权:
std::shared_ptr
允许多个指针实例共享对同一个对象的所有权。这是通过内部的引用计数机制实现的,当最后一个shared_ptr
被销毁或被重置时,对象会被自动删除。 - 自动内存管理:由于引用计数的存在,
std::shared_ptr
能够自动管理内存,减少内存泄漏的风险。 - 异常安全:即使在构造或赋值过程中发生异常,
std::shared_ptr
也能确保资源的正确释放。 - 复制和赋值:
std::shared_ptr
可以被复制和赋值,每次复制都会增加内部引用计数。 - 可空性:
std::shared_ptr
可以存储空指针,这使得它在某些情况下可以作为普通指针的替代品。
注意事项
- 循环引用问题:如果两个或多个对象相互持有对方的引用,这将导致引用计数永远不会达到零,从而产生内存泄漏。这可以通过使用
std::weak_ptr
来解决 std::shared_ptr
的创建和复制比裸指针稍贵,因为它们需要维护引用计数
语法
std::shared_ptr
作为函数的形参:值传递、引用传递、指针传递都行,推荐直接值传递,这样比较简单
1 | void process(std::unique_ptr<int> ptr); |
std::weak_ptr
std::weak_ptr
是C++标准库中的智能指针,它提供了一种不拥有对象所有权的观察方式,通常与std::shared_ptr
配合使用
特性
- 弱拥有权:
std::weak_ptr
不拥有它所指向的对象的所有权。它只是观察由std::shared_ptr
管理的对象,并不增加对象的引用计数 - 解决循环引用:
std::weak_ptr
常用于解决std::shared_ptr
之间可能形成的循环引用问题 - 延迟访问:
std::weak_ptr
可以延迟对对象的访问,直到确定对象仍然有效 - **转换为
shared_ptr
**:std::weak_ptr
可以被转换为std::shared_ptr
,如果对象仍然存活。如果对象已经被销毁,转换将返回一个空的shared_ptr
- 自动重置:当
std::weak_ptr
观察的对象被销毁时,std::weak_ptr
会自动变为空
语法
创建std::weak_ptr
1 |
|
访问对象
1 | if (weak.lock() != nullptr) { |
检查是否为空
1 | if (weak.expired()) { |
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.