卡码笔记-最强八股文
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
首页
计算机基础
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
简历专栏
代码随想录 (opens new window)
  • 本栏必读

    • 关于本专栏
    • C++学习路线
    • C++面试题系优化
  • 基础与语法

  • 面向对象

  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

  • 智能指针

    • 什么是智能指针,C++中有哪几种智能指针
      • 简要回答
      • 详细回答
      • 知识拓展
    • 智能指针的实现原理是什么?
    • C++11中的智能指针线程安全性
  • 并发与 I/O

# C++智能指针的区别与选型

面试官问"C++ 有哪几种智能指针,区别是什么",大多数人能列出三个名字,但追问"什么时候该用 unique_ptr、什么时候该用 shared_ptr"就答不清楚了。这道题考的不是背定义,而是你对所有权语义的理解深度。

# 简要回答

三种智能指针本质上对应三种所有权模型:unique_ptr 独占(同一时刻只有一个拥有者)、shared_ptr 共享(多个拥有者通过引用计数协调)、weak_ptr 观察(不参与所有权,只是"看一眼还在不在")。选型的核心原则是:能用 unique_ptr 就不用 shared_ptr,需要打破循环引用才用 weak_ptr。

# 详细回答

智能指针的底层思想是 RAII——把资源的生命周期绑定到对象的生命周期上,构造时获取资源,析构时自动释放,彻底消灭手动 delete 带来的泄漏风险。

unique_ptr — 独占所有权

同一时刻只有一个 unique_ptr 拥有资源。禁止拷贝,只能移动(std::move)。析构时直接 delete,零开销,性能和裸指针一样。90% 的场景应该优先用它——函数内部的局部资源、类的成员变量、工厂函数的返回值,都适合 unique_ptr。

shared_ptr — 共享所有权

多个 shared_ptr 可以指向同一个对象,内部通过引用计数管理生命周期。最后一个 shared_ptr 析构时释放资源。代价是每次拷贝/析构都要原子操作引用计数,比 unique_ptr 重。只有在确实需要多个拥有者的场景才用——比如缓存、观察者模式中的共享资源。

weak_ptr — 弱引用/观察者

不增加引用计数,不参与生命周期管理。通过 lock() 尝试提升为 shared_ptr,如果对象已死就返回空。唯一用途:打破 shared_ptr 的循环引用,或者在不确定对象是否还活着时安全地"探测"一下。

选型决策很简单:默认用 unique_ptr;如果资源确实需要被多处共享,用 shared_ptr;如果出现了循环引用或者需要非拥有性观察,用 weak_ptr。

智能指针选型对比

# 知识拓展

Q:为什么说 unique_ptr 是零开销的?

因为它内部就是一个裸指针,没有引用计数、没有控制块、没有原子操作。编译器优化后,unique_ptr 和裸指针生成的机器码完全一样。

Q:shared_ptr 的性能代价具体在哪?

两方面:一是多了一个控制块的堆分配(用 make_shared 可以合并为一次分配);二是每次拷贝和析构都要做原子加减操作,在高并发场景下这个开销不可忽视。

Q:循环引用是怎么发生的?

A 持有 shared_ptr 指向 B,B 也持有 shared_ptr 指向 A。两者的引用计数永远不会归零,内存永远不会释放。解决办法是把其中一方改成 weak_ptr——weak_ptr 不增加引用计数,打破了循环。

Q:能不能用 unique_ptr 代替 shared_ptr?

如果你能把所有权链条理清楚(谁创建、谁拥有、谁负责销毁),绝大多数场景都可以用 unique_ptr。shared_ptr 往往是"懒得想所有权"的妥协方案,用多了反而容易引入循环引用和性能问题。

Last Updated: 5/28/2026, 4:45:41 PM

← C++中的协程概念及实现 智能指针的实现原理是什么? →

评论

验证登录状态...

侧边栏 侧边栏
夜间模式 夜间
卡码简历 卡码简历
代码随想录 代码随想录
卡码投递表 卡码投递表🔥
2026实习校招群 2026群
添加客服微信 2026实习校招客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记 支持卡码笔记
鼓励/支持/赞赏Carl 卡码笔记赞赏码
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪