跳转至

标准库-智能指针

现代C++中的智能指针主要有三种类型:unique_ptrshared_ptrweak_ptr。它们都定义在 <memory> 头文件中,旨在安全地管理动态内存,避免内存泄漏和悬空指针问题。建议在现代C++中尽可能使用智能指针,替代原始的 newdelete

如果熟悉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有额外的性能开销,因为它需要维护引用计数,谨慎的使用它。