标准库-智能指针
现代C++中的智能指针主要有三种类型:unique_ptr
、shared_ptr
和 weak_ptr
。它们都定义在 <memory>
头文件中,旨在安全地管理动态内存,避免内存泄漏和悬空指针问题。建议在现代C++中尽可能使用智能指针,替代原始的 new
和 delete
。
如果熟悉Rust,可以基本将三类智能指针做如下类比(事实上智能指针起源于C++,Rust才是借鉴者):
C++智能指针 | Rust所有权智能指针 | 主要特征 |
---|---|---|
unique_ptr |
Box<T> |
独占所有权,作用域结束自动释放 |
shared_ptr |
Arc<T> |
共享所有权,引用计数 |
weak_ptr |
Weak<T> |
弱引用,避免循环引用 |
Unique Ptr
std::unique_ptr
是一种独占所有权的智能指针,意味着同一时间内只能有一个unique_ptr
拥有对对象的控制权。它不能被复制到其他unique_ptr
对象,只能被移动,这确保了其独占所有权的特性。
#include <memory>
int main() {
auto ptr = std::make_unique<int>(10); // 使用make_unique创建一个int类型的unique_ptr
}
Shared Ptr & Weak Ptr
std::shared_ptr
是一种共享所有权的智能指针,允许多个指针实例指向同一个对象。当最后一个拥有它的shared_ptr
被销毁或者重新赋值后,它所管理的对象会被自动删除。所以,一旦出现循环引用,可以导致内存泄漏。循环引用时使用std::weak_ptr
来打破循环。
std::shared_ptr
内部使用原子操作来管理其引用计数,这意味着在多个线程中对同一shared_ptr
实例进行拷贝构造或赋值操作是安全的。尽管std::shared_ptr
的引用计数是线程安全的,被指向的对象本身并不一定是线程安全的。如果多个线程需要访问或修改同一个对象的数据,这个对象自身需要进行适当的同步操作,如使用互斥锁。所以,在上表中我将shared_ptr
类比于Arc
而不是Rc
。
shared_ptr
有额外的性能开销,因为它需要维护引用计数,谨慎的使用它。