一、核心概念深入解析
一、核心概念深入解析
1. shared_ptr
的线程安全性澄清
- 引用计数是原子操作:
shared_ptr
的引用计数(use_count
)在多线程中递增 / 递减是安全的(原子操作),但对象本身的读写需额外同步(如std::mutex
)。 - 误区纠正:线程安全仅针对计数管理,若多个线程同时修改对象数据,仍需加锁避免数据竞争。
2. shared_ptr
构造方式对比
方式 | 示例 | 安全性 | 性能 | 推荐度 |
---|---|---|---|---|
直接构造(显式) | shared_ptr<int> p(new int(42)); | 需避免裸指针重复使用 | 中等 | ★★☆☆☆ |
工厂函数 make_shared | auto p = make_shared<int>(42); | 安全(避免裸指针) | 优(单次分配) | ★★★★★ |
拷贝 / 移动构造 | shared_ptr<int> p2 = p1; | 安全 | 优 | ★★★★☆ |
make_shared
优势:- 减少内存分配次数(对象和控制块一次分配)。
- 避免表达式求值顺序导致的潜在泄漏(如
shared_ptr(populate(), commit())
中若populate
抛异常,commit
可能未调用)。
3. 删除器(Deleter)的高级用法
- 类型:可以是函数指针、lambda、函数对象。
- 示例:lambda 删除器
cpp
shared_ptr<FILE> file(fopen("test.txt", "w"), [](FILE* fp) { fclose(fp); cout << "File closed\n"; });
- 数组管理:
cpp
shared_ptr<int> arr(new int[5], [](int* p) { delete[] p; }); // 自定义删除器处理数组
4. 循环引用的本质与解决
- 场景:双向链表节点互相持有
shared_ptr
cpp
class Node { public:shared_ptr<Node> next;shared_ptr<Node> prev;~Node() { cout << "Node destroyed\n"; } };int main() {auto a = make_shared<Node>();auto b = make_shared<Node>();a->next = b; // a强引用b(b计数+1)b->prev = a; // b强引用a(a计数+1)// 离开作用域时,a和b计数均为1(循环引用),无法释放 → 内存泄漏 }
- 解决方案:用
weak_ptr
打破强引用cpp
class Node { public:shared_ptr<Node> next;weak_ptr<Node> prev; // 弱引用,不影响计数~Node() { cout << "Node destroyed\n"; } }; // 此时,a和b计数均为1,离开作用域时正常释放
5. weak_ptr
的核心特性
- 不影响引用计数:
weak_ptr
构造 / 赋值时,shared_ptr
计数不变。 - 访问数据的唯一方式:
cpp
weak_ptr<int> wp(sp); // wp观察sp if (auto tmp = wp.lock()) { // 转换为shared_ptr,非空时访问cout << *tmp << endl; }
- 用途:
- 避免循环引用。
- 实现 “观察者模式”(观察共享资源是否存在)。
- 缓存(如缓存对象,存在时直接使用,不存在时重建)。
二、面试高频问题与回答模板
问题 1:shared_ptr 循环引用是什么?如何解决?
回答:
循环引用指两个或多个 shared_ptr
互相强引用,导致引用计数无法归零,内存无法释放。
示例:双向链表节点互相持有 shared_ptr
,形成环。
解决方案:
将其中一个引用改为 weak_ptr
(弱引用),weak_ptr
不增加计数,打破循环。
cpp
class Node {
public:shared_ptr<Node> next;weak_ptr<Node> prev; // 弱引用
};
问题 2:weak_ptr 有什么作用?如何访问其指向的数据?
回答:
weak_ptr
是 shared_ptr
的辅助类,用于:
- 解决循环引用(弱引用不影响计数)。
- 观察
shared_ptr
是否存在(通过lock()
检查)。
访问数据步骤:
cpp
weak_ptr<int> wp(sp); // 关联shared_ptr
if (auto locked_sp = wp.lock()) { // 转换为shared_ptr,非空时有效cout << *locked_sp << endl; // 通过shared_ptr访问
}
问题 3:shared_ptr 和 unique_ptr 的区别?
回答:
特性 | shared_ptr | unique_ptr |
---|---|---|
所有权 | 共享(多个指针指向同一资源) | 独占(唯一所有权) |
引用计数 | 有 | 无 |
拷贝 / 赋值 | 允许(计数变化) | 禁止(仅可移动) |
适合场景 | 多指针共享资源 | 独占资源(如函数返回值) |
性能 | 稍低(计数开销) | 更高 |
问题 4:为什么推荐使用 make_shared 而非直接 new?
回答:
- 性能优化:
make_shared
一次分配内存(对象 + 控制块),减少new
和delete
次数。 - 异常安全:避免表达式求值顺序导致的资源泄漏(如
shared_ptr(populate(), commit())
中若populate
抛异常,commit
可能未调用,而make_shared
无此问题)。 - 代码简洁:自动推导类型,无需显式指定模板参数(
auto
配合使用)。
问题 5:shared_ptr 如何管理非堆内存资源(如文件句柄)?
回答:
通过自定义删除器指定释放逻辑,而非默认的 delete
。
示例:
cpp
void fclose_deleter(FILE* fp) { fclose(fp); }
shared_ptr<FILE> file(fopen("test.txt", "r"), fclose_deleter);
// 或用lambda:
// shared_ptr<FILE> file(fopen("test.txt", "r"), [](FILE* fp){ fclose(fp); });
三、总结:面试核心考点
shared_ptr
原理:引用计数、RAII、线程安全边界(计数安全,对象操作需同步)。- 最佳实践:优先
make_shared
,避免裸指针,用weak_ptr
解决循环引用。 weak_ptr
定位:辅助shared_ptr
,仅观察不持有资源,需通过lock()
访问数据。- 场景题:能结合双向链表等场景,分析循环引用成因并给出解决方案。
通过以上梳理,可系统掌握 shared_ptr
/weak_ptr
的核心知识,从容应对面试中的原理分析与场景题。
相关文章:
一、核心概念深入解析
一、核心概念深入解析 1. shared_ptr 的线程安全性澄清 引用计数是原子操作:shared_ptr 的引用计数(use_count)在多线程中递增 / 递减是安全的(原子操作),但对象本身的读写需额外同步(如 std:…...
python直方图
在Python中,绘制直方图(Histogram)是一项非常常见的任务,通常用于数据可视化,以展示数据的分布情况。Python中有多种库可以绘制直方图,其中最常用的两个库是Matplotlib和Seaborn。此外,Pandas库…...
[特殊字符] Unity 性能优化终极指南 — Text / TextMeshPro 组件篇
UGUI Text组件的不当使用及其性能瓶颈与优化 在Unity UGUI系统中,Text 组件(或其升级版 TextMeshPro)是显示文本信息的核心元素。然而,如果不当使用,它极易成为UI性能瓶颈的罪魁祸首,尤其是在预制体、属性…...

Idea 配置 Maven 环境
下载 Maven 官网:https://maven.apache.org/index.html 点击左侧 Downloads,然后选择 Files 中的 zip 包下载(下载慢可以使用迅雷) 配置 Maven 将压缩包解压,比如我解压后放到了 D:\developer\environment\apache-…...
git clone报错:SSL certificate problem: unable to get local issuer certificate
上述报错的完整信息是: Cloning into test... fatal: unable to access https://github.com/xxxx/xxxx.git/: SSL certificate problem: unable to get local issuer certificate 该报错表示 Git 在使用 HTTPS 协议克隆仓库时,无法验证 GitHub 的 SSL …...

Kafka 如何保证不重复消费
在消息队列的使用场景中,避免消息重复消费是保障数据准确性和业务逻辑正确性的关键。对于 Kafka 而言,保证不重复消费并非单一机制就能实现,而是需要从生产者、消费者以及业务层等多个维度协同配合。接下来,我们将结合图文详细解析…...
SpringBoot整合MyBatis完整实践指南
在Java企业级应用开发中,SpringBoot和MyBatis的组合已经成为主流的技术选型方案之一。本文将详细介绍如何从零开始搭建一个基于SpringBoot和MyBatis的项目,包括环境配置、数据库设计、实体类创建、Mapper接口编写以及实际应用等完整流程。 一、环境准备…...

RNN结构扩展与改进:从简单循环网络到时间间隔网络的技术演进
本文系统介绍 RNN 结构的常见扩展与改进方案。涵盖 简单循环神经网络(SRN)、双向循环神经网络(BRNN)、深度循环神经网络(Deep RNN) 等多种变体,解析其核心架构、技术特点及应用场景,…...
docker中,容器时间和宿机主机时间不一致问题
win11下的docker中有个mysql。今天发现插入数据的时间不正确。后来发现原来是docker容器中的时间不正确。于是尝试了各种修改,什么run -e TZ"${tzutil /g}",TZ"Asia/Shanghai",还有初始化时带--mysqld一类的,…...
Unity Shader编程】之高级纹理
一,立方体纹理 Cubemap 用途 用途说明反射贴图表面镜面高光或金属反射环境光采样模拟环境对物体的影响天空盒背景使用六张图拼接场景背景全景投影做360度相机渲染、投影等 二,创建立方体纹理 在 Unity 中创建和保存一个 立方体纹理(Cubema…...

类 Excel 数据填报
类 Excel 填报模式,满足用户 Excel 使用习惯 数据填报,可作为独立的功能模块,用于管理业务流程、汇总采集数据,以及开发各类数据报送系统,因此,对于报表工具而言,其典型场景之一就是利用报表模…...
vscode调试stm32,Cortex Debug的配置文件lanuch.json如何写,日志
https://blog.csdn.net/jiladahe1997/article/details/122046665 https://discuss.em-ide.com/blog/67-cortex-debug 第一版 {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?li…...

Office文档图片批量导出工具
软件介绍 本文介绍一款专业的Office文档图片批量导出工具。 软件特点 这款软件能够批量导出Word、Excel和PPT中的图片,采用绿色单文件设计,体积小巧仅344KB。 基本操作流程 使用方法十分简单:直接将Word、Excel或PPT文件拖入软件…...

【iOS】ARC 与 Autorelease
ARC 与 Autorelease 文章目录 ARC 与 Autorelease前言何为ARC内存管理考虑方式自己生成的对象,自己持有非自己生成的对象,自己也可以持有不再需要自己持有的对象时释放非自己持有的对象无法释放 ARC的具体实现编译期和运行期ARC做的事情ARC实现: __autoreleasing 与 Autoreleas…...
人工智能在智能零售中的创新应用与未来趋势
随着电子商务的蓬勃发展和消费者需求的不断变化,零售行业正面临着前所未有的挑战和机遇。智能零售作为零售行业的重要发展方向,通过引入人工智能(AI)、物联网(IoT)、大数据和云计算等前沿技术,正…...
业务材料——半导体行业MES系统核心功能工业协议AI赋能
一、前置概念 半导体行业 半导体行业主要生产基于半导体材料(如硅、锗、化合物半导体等)的电子元器件及相关产品,广泛应用于计算、通信、能源、医疗等领域。 MES系统 MES系统(Manufacturing Execution System,制造…...
docker部署命令行 — 启动一个 MySQL 数据库服务 并且把它的数据存储挂载到卷(volume)里
挂载卷的配置写法: version: "3" services:db:image: mysqlvolumes:- mysql_data:/var/lib/mysqlvolumes:mysql_data:这段 docker-compose.yml 配置非常典型,是用来启动一个 MySQL 数据库服务 并且把它的数据存储挂载到卷(volume&…...

铁电液晶破局 VR/AR:10000PPI 重构元宇宙显示体验
一、VR/AR 沉浸感困境:传统显示技术的天花板在哪? (一)纱窗效应与眩晕感:近眼显示的双重枷锁 当用户戴上 VR 头显,眼前像素网格形成的 “纱窗效应” 瞬间打破沉浸感。传统液晶 500-600PPI 的像素密度&…...
2025年微信小程序开发:AR/VR与电商的最新案例
引言 微信小程序自2017年推出以来,已成为中国移动互联网生态的核心组成部分。根据最新数据,截至2025年,微信小程序的日活跃用户超过4.5亿,总数超过430万,覆盖电商、社交、线下服务等多个领域(WeChat Mini …...
从零开始,学会上传,更新,维护github仓库
以下是一份从头到尾、覆盖安装、配置、创建仓库、上传项目到 GitHub 的完整教程。全程使用通用示例,不包含任何具体的仓库链接,仅供参考。 一、准备工作 1. 注册 GitHub 账号 打开浏览器,访问 GitHub 官网(输入 “GitHub” 即可找…...
#STM32 HAL库实现的STM32F407时钟配置程序以及和STM32F103配置对比
以下是使用STM32 HAL库实现的STM32F407时钟配置完整代码(基于8MHz外部晶振,配置为168MHz系统时钟),包含详细注释和关键点说明: 完整HAL库实现(system_stm32f4xx.c main.c) 1. 首先在stm32f4xx…...

竞争加剧,美团的战略升维:反内卷、科技与全球化
5月26日,美团发布2025年第一季度业绩报告,交出了一份兼具韧性与创新性的成绩单。 报告显示,公司一季度总营收866亿元,同比增长18%;核心本地商业收入643亿元,同比增长18%;季度研发投入58亿元&a…...

(17)课36:窗口函数的例题:例三登录时间与连续三天登录,例四球员的进球时刻连续进球。
(89)例三登录时间 : 保留代码版本 : CREATE TABLE sql_8( user_id varchar(2), login_date date ); insert into sql_8(user_id,login_date) values(A,2024-09-02),(A,2024-09-03),(A,2024-09-04),(B,2023-11-25),(B,2023-12- 3…...

高性能分布式消息队列系统(二)
上一篇博客将C进行实现消息队列的用到的核心技术以及环境配置进行了详细的说明,这一篇博客进行记录消息队列进行实现的核心模块的设计 五、项目的需求分析 5.1、项目框架的概念性理解 5.1.1、消息队列的设计和生产消费者模型的关系 在现代系统架构中,…...
Spring 官方推荐构造函数注入
1. 依赖关系明确 构造函数注入可以清晰地声明类的依赖关系,所有必需的依赖项都通过构造函数参数传递,使得代码的可读性更高。这种方式让类的使用者能够直观地了解类的依赖,而不需要通过注解或反射来猜测。 2. 增强代码健壮性 构造函数注入…...

华为OD机试真题——天然蓄水库(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《天然蓄水库》: 目录 题目…...

【Harmony OS】数据存储
目录 数据存储概述 首选项数据存储 关系型数据库 数据存储概述 • 数据存储 是为了解决应用数据持久化问题,使得数据能够存储在外存中,达到保存或共享目的。 • 鸿蒙应用数据存储包括 本地数据存储 和 分布式数据存储 。 • 本地数据存储 为应用…...

MybatisPlus--核心功能--service接口
Service接口 基本用法 MyBatisPlus同时也提供了service接口,继承后一些基础的增删改查的service代码,也不需要去书写。 接口名为Iservice,而Iservice也继承了IRepository,这里提供的方法跟BaseMapper相比只多不少,整…...

uniapp调试,设置默认展示的toolbar内容
uniapp调试,设置默认展示的toolbar内容 设置pages.json中 pages数组中 json的顺序就可以只需要调整顺序,不会影响该bar在页面中的显示默认展示第一条page...

笔记本电脑开机无线网卡自动禁用问题
1.问题环境 电脑品牌:华硕笔记本天选4 电脑型号:FX507VV 电脑系统:windows 11_x64_24h2 文档编写时间:2025年6月 2.问题现象 1. 笔记本电脑开机之后自动禁用无线网卡 使用USB转RJ45转接头同样无效,这个网卡也给禁…...