博客主页:【夜泉_ly】
本文专栏:【泉面 TOP150】
欢迎点赞👍收藏⭐关注❤️

前言
泉面 TOP150 系列是由我的 泉面 项目收集了 1w+ 真实面经 后,
提取出了其中的 15w+ 题目,并进行聚簇、排序,得到的面试常考题。
我会对每道题进行整理,从 答题要点 ,到 3 分钟详答 ,1 分钟简答 ,再到常见追问全链路覆盖。
希望能减轻我和各位的复习压力,让我们面对基础八股题时有话可说。
啊,顺带提一句,大家回答八股题时,一定要确保自己说的每个词都理解了,
不然被追问到了是很痛苦和尴尬的。
再提一句,个人能力有限,如有错误,欢迎指正。
一、题目考察点
这道题表面问"智能指针是什么",本质在考察:
- 内存管理能力:是否理解RAII、资源生命周期管理
- C++核心机制理解:对象所有权、拷贝/移动语义
- 工程经验:是否在实际项目中用过、踩过坑
- 风险意识:是否知道循环引用、线程安全等问题
- 表达结构能力:能否把基础概念讲清楚且有层次
二、答题关键标签
【RAII】通过对象生命周期管理资源释放
【所有权语义】明确资源归属与管理责任
【unique_ptr】独占所有权,不可拷贝可移动
【shared_ptr】引用计数,共享所有权
【weak_ptr】解决循环引用,不参与计数
【循环引用】shared_ptr相互持有导致内存泄漏
【线程安全】shared_ptr计数原子操作但对象不保证安全
三、3分钟详答版
智能指针本质上是一个封装了原始指针的类,通过RAII机制在对象生命周期结束时自动释放资源,从而避免手动delete带来的内存泄漏和异常安全问题。
在C++11之后,常用的智能指针主要有三种,分别是unique_ptr、shared_ptr和weak_ptr,它们的核心区别在于所有权模型。
unique_ptr表示独占所有权,同一时间只能有一个指针拥有这块资源,它不支持拷贝,只支持移动语义,这样可以在编译期就保证资源不会被多个对象同时管理,适合表示明确归属的资源,比如函数返回值或局部资源管理。
shared_ptr采用引用计数机制,允许多个指针共享同一块资源,每拷贝一次计数加一,析构时减一,当计数为0时才真正释放资源。这种方式适合不确定生命周期、需要共享的数据,但它的开销比unique_ptr更高,因为涉及引用计数和原子操作。
weak_ptr是为了解决shared_ptr的循环引用问题而设计的,它本身不增加引用计数,只是一个观察者,可以通过lock转成shared_ptr使用。典型场景是两个对象互相持有shared_ptr,如果不用weak_ptr,会导致引用计数永远不为0,从而内存无法释放。
从工程角度来看,智能指针解决了两个核心问题:一是异常安全,比如函数中途抛异常时资源仍然能释放;二是代码可维护性,避免手动管理生命周期带来的复杂性。
需要注意的是,shared_ptr虽然线程安全地维护引用计数,但它管理的对象本身并不保证线程安全;另外,在性能敏感场景下要谨慎使用shared_ptr,因为引用计数带来的开销不可忽略。
一般实践中,优先使用unique_ptr表达所有权,只有在确实需要共享时才使用shared_ptr,同时注意避免循环引用问题。
四、1分钟简答版
智能指针是对原始指针的封装,基于RAII机制,在对象析构时自动释放资源,主要解决内存泄漏和异常安全问题。
常见的有三种:unique_ptr、shared_ptr和weak_ptr。
unique_ptr是独占所有权,不可拷贝,只能移动,适合明确归属的资源;
shared_ptr通过引用计数实现共享所有权,多个指针可以指向同一对象,但有额外开销;
weak_ptr不参与引用计数,主要用来解决shared_ptr的循环引用问题。
实际使用中一般优先用unique_ptr,只有在确实需要共享时才用shared_ptr,同时注意循环引用和性能开销。
五、常见追问
-
shared_ptr是线程安全的吗?
作答思路:引用计数是原子操作线程安全,但所管理对象本身不保证线程安全。
-
weak_ptr为什么能解决循环引用?
作答思路:不增加引用计数,打破强引用环,使计数能归零释放资源。
-
unique_ptr为什么不能拷贝?
作答思路:为了保证唯一所有权,避免多个指针管理同一资源导致重复释放。
-
shared_ptr的实现原理是什么?
作答思路:控制块中维护引用计数和弱引用计数,资源和计数分离。
-
shared_ptr什么时候释放资源?
作答思路:引用计数减为0时触发析构释放。
-
智能指针一定比裸指针好吗?
作答思路:不是,性能敏感或不涉及所有权时裸指针更合适。
-
make_shared和直接new有什么区别?
作答思路:一次内存分配更高效,减少碎片,但控制块和对象绑定。
-
循环引用的典型场景?
作答思路:双向链表或父子节点互相持有shared_ptr。

希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!