Skip to content

智能指针(Smart Pointers)专题 ​

一句话总览 ​

智能指针是 RAII(资源获取即初始化)思想的产物:把「裸指针 + 手动 delete」封装进对象,让内存(或任意资源)随对象生命周期自动释放。C++11 起标准库提供 unique_ptr、shared_ptr、weak_ptr。

三类智能指针速览 ​

智能指针所有权特点代价 / 限制
unique_ptr独占轻量、无额外内存开销、可自定义删除器不可拷贝,只可 move
shared_ptr共享引用计数,最后一个释放时销毁对象控制块开销 + 原子计数,有循环引用风险
weak_ptr观察不增加引用计数,可升级为 shared(lock)专破循环引用 / 缓存观测

高频问题清单(含答案) ​

1. 为什么需要智能指针?RAII 是什么?

答案

RAII(资源获取即初始化)把资源生命周期绑定到对象生命周期,析构自动释放;智能指针借此避免忘 delete、异常路径泄漏、重复释放。

2. unique_ptr 能否拷贝?如何转移所有权?

答案

不可拷贝(拷贝构造/赋值被 =delete),只能移动。用 std::move(up) 把所有权转移到另一个 unique_ptr,源变空。

3. shared_ptr 引用计数存在哪、是否线程安全?

答案

存在堆上的控制块(control block)里,多个 shared_ptr 共享。计数增减是原子操作、线程安全;但被指对象本身的访问不因 shared_ptr 而自动线程安全。

4. weak_ptr 的作用?如何打破循环引用?

答案

weak_ptr 不增加引用计数、是观察者;lock() 成功则临时提升为 shared_ptr 安全访问。A、B 互相持有 shared_ptr 会循环引用(计数永不归零泄漏),把其中一方换成 weak_ptr 即可打破。

5. 手写 shared_ptr / unique_ptr(高频压轴题)

答案

unique_ptr 存裸指针 + 删除器,禁拷贝、实现移动;shared_ptr 用指针 + 控制块(强/弱计数),拷贝增计数、析构减到零则 delete。完整实现见 手写实现专题 · 手写智能指针。

6. shared_ptr 的 control block 布局?make_shared 优点?

答案

控制块含强计数、弱计数、删除器、分配器。make_shared 把对象和控制块一次分配(省一次 malloc、缓存更友好),缺点是 weak_ptr 会拖住整块内存直到弱计数也归零。

7. 智能指针 + 裸指针混用有什么坑?

答案

用同一裸指针建多个 shared_ptr 会各自计数、导致 double free;shared_ptr 释放后裸指针悬垂。应尽量用 make_shared/make_unique,避免裸指针与智能指针混用。

8. enable_shared_from_this 为什么存在?

答案

让对象能从自己的 this 安全地得到 shared_ptr(内部持有 weak_ptr),避免从裸 this 再建一个 shared_ptr 造成 double free。

9. 自定义删除器怎么传?

答案

unique_ptr 删除器是模板参数(类型的一部分、无额外开销、每个对象可不同);shared_ptr 删除器存在控制块(同类型 shared_ptr 可各自带不同删除器)。

10. 智能指针会不会导致内存泄漏?

答案

会。shared_ptr 循环引用(A↔B 互相持有)使计数永不归零 → 泄漏。用 weak_ptr 打破循环。详见 weak_ptr.md。

子文档 ​

文件内容
unique_ptr.md独占所有权、move、删除器、手写
shared_ptr.md引用计数、控制块、make_shared、线程安全、手写
weak_ptr.md循环引用、lock、expired
../handwrite/smart-pointer.md手写实现已迁到 手写实现专题:shared_ptr 控制块 + weak_ptr::lock + make_shared,另有容器 / optional / flat hashmap / 并发件

糌粑的面经笔记 · VitePress 版