一、什么是智能指针

智能指针本质上是一个对象,它像普通指针一样指向堆内存,但同时负责在合适的时机自动释放资源。
其核心思想是:

对象生命周期结束时,资源自动释放

这正是 RAII(Resource Acquisition Is Initialization,资源获取即初始化)的典型应用。


二、C++ 提供的三种智能指针

C++11 之后,标准库 <memory> 中提供了三种常用智能指针。

1. std::unique_ptr —— 独占式所有权

unique_ptr 表示唯一所有权,同一时间只能有一个指针管理该资源。

特点:

  • 不可拷贝,只能移动

  • 零额外引用计数,性能最好

  • 适合明确生命周期的资源

示例:


std::unique_ptr<int> p = std::make_unique<int>(10); // std::unique_ptr<int> q = p; // 错误 std::unique_ptr<int> q = std::move(p);

使用场景:
函数内部对象、容器元素、明确“谁负责释放”的情况。


2. std::shared_ptr —— 引用计数共享

shared_ptr 允许多个指针共享同一资源,内部通过引用计数决定何时释放内存。

特点:

  • 可拷贝

  • 引用计数为 0 时释放资源

  • 有一定性能开销

示例:


std::shared_ptr<int> p1 = std::make_shared<int>(20); std::shared_ptr<int> p2 = p1; // 引用计数 +1

适用场景:
对象被多个模块、函数或线程共同使用,生命周期不清晰。


3. std::weak_ptr —— 解决循环引用

weak_ptr 是对 shared_ptr弱引用,不会增加引用计数。

用途:

  • 打破 shared_ptr 的循环引用

  • 安全观察对象是否仍然存在

示例:


std::weak_ptr<int> wp = p1; if (auto sp = wp.lock()) { // 对象仍然存在 }

如果两个对象互相持有 shared_ptr,会导致引用计数永远不为 0,内存无法释放,此时必须引入 weak_ptr


三、为什么要优先使用 make_shared / make_unique

相比直接使用 new,推荐使用:

  • std::make_unique

  • std::make_shared

优势:

  1. 异常安全(避免内存泄漏)

  2. 代码更简洁

  3. make_shared 可减少一次内存分配


四、智能指针使用原则总结

  • 默认使用 unique_ptr

  • 需要共享时才使用 shared_ptr

  • 出现循环依赖时引入 weak_ptr

  • 避免智能指&#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961944683872553
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961944683872553/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961945577242874
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961945577242874/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961941290685294
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961941290685294/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961941261297428
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961941261297428/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961939768128713
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961939768128713/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961936504980642
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961936504980642/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961935649329902
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961935649329902/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961934412019117
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961934412019117/i
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961931819934629
    &#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#119;&#119;&#119;&#46;&#122;&#104;&#105;&#104;&#117;&#46;&#99;&#111;&#109;/zvideo/1995961931819934629/i
    针混用裸指针管理同一资源

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐