资讯动态

在 C++ 中,`std::shared_ptr` 是标准库(自 C++11 起)提供的一种智能指针(Smart Pointer),位于 `<memory>` 头文件中

发布时间:2026/8/5 12:09:16 来源:尧图企业网站定制
在 C 中std::shared_ptr是标准库自 C11 起提供的一种智能指针Smart Pointer位于memory头文件中。它的主要作用是自动管理动态分配的内存堆内存彻底告别手动new/delete从而防止内存泄漏Memory Leak和悬挂指针Dangling Pointer/野指针。一、 核心机制引用计数Reference Countingstd::shared_ptr采用的是共享所有权Shared Ownership模型。多个 shared_ptr 共享同一块内存你可以把同一个对象赋值给多个std::shared_ptr指针。引用计数器Control Block在内部它维护了一个全局计数器记录当前有多少个shared_ptr正在指向这块内存。每当有一个新的shared_ptr指向该内存比如赋值、拷贝引用计数1。每当有一个shared_ptr离开作用域或被销毁引用计数-1。当引用计数降为0时系统会自动调用delete释放该内存。二、 基础使用示例#includeiostream#includememory// 必须引入头文件classMyClass{public:MyClass(){std::cout构造函数被调用\n;}~MyClass(){std::cout析构函数被调用内存释放\n;}voiddo_something(){std::cout执行操作...\n;}};intmain(){// 1. 创建 shared_ptr强烈推荐使用 std::make_shared效率更高且异常安全std::shared_ptrMyClassptr1std::make_sharedMyClass();std::cout当前引用计数: ptr1.use_count()std::endl;// 输出 1{// 2. 拷贝 ptr1 给 ptr2共享同一个对象std::shared_ptrMyClassptr2ptr1;std::cout拷贝后引用计数: ptr1.use_count()std::endl;// 输出 2ptr2-do_something();// 像普通指针一样通过 - 访问成员}// 3. ptr2 离开内部作用域被析构引用计数 -1std::coutptr2 销毁后引用计数: ptr1.use_count()std::endl;// 输出 1return0;}// 4. ptr1 离开 main 函数作用域引用计数降为 0对象被自动 delete三、 为什么在并发和设计模式中经常看到它在前面的多线程安全栈threadsafe_stack中我们用到了std::shared_ptr解决异常安全与所有权转移在并发环境下如果pop()函数直接返回值对象如T pop()若返回值拷贝构造失败抛出异常原本要弹出的元素可能已经丢失。而如果返回std::shared_ptrT堆内存的分配在弹出之前就完成。传递智能指针本身只是拷贝指针和增加引用计数不会抛出异常保证了操作的原子性和安全性。跨线程共享数据生命周期在多线程中你往往无法预知哪一个线程会最后结束并使用完数据。使用std::shared_ptr最后一个持有所指对象的线程退出时会自动清理内存避免了线程间“谁来负责delete”的扯皮问题。四、 使用注意事项陷阱循环引用Circular Reference如果对象 A 内部有一个指向 B 的shared_ptr而对象 B 内部也有一个指向 A 的shared_ptr双方的引用计数永远无法降到 0导致内存泄漏。解决方法将其中一端的引用改为std::weak_ptr弱引用指针不增加引用计数。性能开销相比裸指针或std::unique_ptr独占所有权shared_ptr内部需要维持额外的控制块且引用计数的加减是原子操作Thread-safe atomic operations会有微小的性能开销。线程安全性shared_ptr的引用计数本身是线程安全的原子操作。但它指向的对象本身的访问不是线程安全的对对象内容的读写仍需要配合std::mutex。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价