C++ 现代编程实践:用 make_unique 告别裸 new/delete

发布时间:2026/7/12 10:24:30

C++ 现代编程实践:用 make_unique 告别裸 new/delete
1. 为什么应该抛弃裸 new/delete在 C11 之前动态内存管理几乎是开发者的日常一个new配上若干个delete还要小心异常安全和所有权问题。手动管理内存至少会带来三大痛点内存泄漏delete忘记调用、提前return或者抛出异常时资源就会丢失二次释放与野指针重复删除同一块内存或继续使用已释放的指针会导致未定义行为所有权混乱团队协作时很难从裸指针一眼看出“谁负责释放”容易写出 bug。自 C11 以来标准库提供了std::unique_ptr和std::make_uniqueC14 起让我们可以彻底告别显式new和delete。本文将介绍如何安全、高效地替换现有代码中的裸指针并解释背后的设计动机。2. make_unique 基本用法std::make_unique是创建std::unique_ptr的工厂函数它直接在堆上构造对象并返回一个独占所有权的智能指针。基本形式为auto p std::make_uniqueWidget(arg1, arg2);等价于原先的Widget* raw new Widget(arg1, arg2);但好处是不需要写delete离开作用域时自动释放异常安全即使构造函数抛出异常也不会泄漏先前分配的资源明确表达了“独占所有权”的语义避免了写两次类型名auto配合make_unique减少冗余。3. 替换模式从 new/delete 到 unique_ptr下面通过几个常见场景展示如何系统地将裸指针代码迁移到make_unique。3.1 普通堆对象// 旧代码手动 new/delete void useWidget() { Widget* w new Widget(100); // ... delete w; // 容易忘记还可能被异常跳过 } // 新代码make_unique void useWidget() { auto w std::make_uniqueWidget(100); // ... 不再需要 delete }3.2 类成员变量class Manager { // 旧裸指针 手动管理 Widget* w_; public: Manager() : w_(new Widget(42)) {} ~Manager() { delete w_; } // 还需要拷贝/移动操作……一团乱 }; class Manager { // 新unique_ptr 自动管理生命周期 std::unique_ptrWidget w_; public: Manager() : w_(std::make_uniqueWidget(42)) {} // 析构函数自动释放无需手写 // 移动语义天然支持禁止拷贝 };3.3 容器中的对象指针// 旧vector 中存裸指针销毁前必须逐个 delete std::vectorWidget* widgets; widgets.push_back(new Widget(1)); widgets.push_back(new Widget(2)); for (auto p : widgets) delete p; // 极易漏删 // 新存 unique_ptrclear/析构自动释放 std::vectorstd::unique_ptrWidget widgets; widgets.push_back(std::make_uniqueWidget(1)); widgets.push_back(std::make_uniqueWidget(2)); // 容器销毁时自动释放所有 Widget4. 为什么推荐 make_unique 而不是直接 new unique_ptr你当然可以这样写std::unique_ptrWidget p(new Widget(arg));但是仍然显式写了new违背了“禁止显式 new/delete”的原则。更重要的是make_unique提供了额外的异常安全保证和优化可能某些实现可以减少一次内存分配。此外工厂函数风格使得代码意图更清晰、更容易审计。5. 注意事项与边界场景C11 兼容std::make_unique是 C14 新增的如果还停留在 C11可以自己实现一个简单的版本。自定义删除器unique_ptr支持自定义删除器但make_unique无法传递删除器此时仍需使用new构造unique_ptr。不过现代代码中这类场景很少且通常可以用shared_ptr或封装类替代。数组类型std::make_unique也支持数组例如std::make_uniquechar[](1024)。不过要注意unique_ptrT[]的删除器与标量不同不要混淆。所有权转移需要传递所有权时使用std::move转移unique_ptr本身而不是转移裸指针。与共享所有权的区别当确实需要共享所有权时再考虑std::make_shared。不要因为懒得设计所有权就用shared_ptr一把梭。6. 在团队中推行“禁止 new/delete”可以借助静态分析工具如 clang-tidy 的modernize-make-unique检查项或编译器警告来强制执行这一规则。团队规范中明确写清楚绝对不允许出现裸new和delete所有动态分配都通过std::make_unique或std::make_shared完成裸指针仅用于非拥有性引用且需要标明“不负责释放”。这样不仅能大幅减少内存相关 bug也使得代码更容易被新成员理解和维护。7. 总结用std::make_unique替代裸new/delete是现代 C 的最佳实践之一。它消除了手动资源管理的麻烦提升了异常安全性并且让所有权语义一目了然。本文提供的替换模式和注意事项可以帮助你平滑迁移现有代码并建立一套可靠的编码规范。从今天起让我们对显式new和delete说“不”。

相关新闻

3步掌握小红书无水印下载:新手也能快速上手的XHS-Downloader工具

3步掌握小红书无水印下载:新手也能快速上手的XHS-Downloader工具

2026/7/12 10:14:30

3步掌握小红书无水印下载:新手也能快速上手的XHS-Downloader工具 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用…

STM32L152ZD与MCP3551高精度ADC接口设计与优化

STM32L152ZD与MCP3551高精度ADC接口设计与优化

2026/7/12 10:14:30

1. MCP3551与STM32L152ZD的硬件架构解析MCP3551是Microchip公司推出的一款22位Δ-Σ型模数转换器,采用单电源供电(2.7V-5.5V),内部集成可编程增益放大器(PGA)和低噪声基准电压源。其核心特性包括&#xff1…

蓝牙5.4 LE Audio与STM32的无线音频传输方案

蓝牙5.4 LE Audio与STM32的无线音频传输方案

2026/7/12 10:14:30

1. 项目背景与硬件选型解析 在无线音频传输领域,Bluetooth 5.4标准带来了革命性的改进,特别是LE Audio的引入彻底改变了传统蓝牙音频的传输方式。我们选择IDC777-1蓝牙模块与STM32F417ZG微控制器的组合,正是看中了这套方案在低功耗和高音质之…

Matlab卫星轨道动态仿真工具包:含28组实测PG数据与三维可视化脚本

Matlab卫星轨道动态仿真工具包:含28组实测PG数据与三维可视化脚本

2026/7/12 12:04:44

本文还有配套的精品资源,点击获取 简介:直接运行zhuchengxu.m或main.m,就能生成卫星轨道三维轨迹图、速度矢量图、地心距离随时间变化曲线等结果。工具包内置weixingguidao.m做轨道动力学计算,shujuchuli.m读取Excel格式的实测…

pyisula实战教程:使用Python自动化管理iSulad容器

pyisula实战教程:使用Python自动化管理iSulad容器

2026/7/12 12:04:44

pyisula实战教程:使用Python自动化管理iSulad容器 【免费下载链接】pyisula python sdk library for iSulad and isula-build 项目地址: https://gitcode.com/openeuler/pyisula 前往项目官网免费下载:https://ar.openeuler.org/ar/ pyisula是op…

免费开源虚拟桌面伴侣Mate Engine完整指南:打造个性化数字伙伴的终极方案

免费开源虚拟桌面伴侣Mate Engine完整指南:打造个性化数字伙伴的终极方案

2026/7/12 12:04:44

免费开源虚拟桌面伴侣Mate Engine完整指南:打造个性化数字伙伴的终极方案 【免费下载链接】Mate-Engine A free Desktop Mate alternative with a lightweight interface and custom VRM support, though with more features. 项目地址: https://gitcode.com/gh_m…

QKeyMapper:Windows平台上最完整的开源输入设备映射解决方案

QKeyMapper:Windows平台上最完整的开源输入设备映射解决方案

2026/7/12 12:04:44

QKeyMapper:Windows平台上最完整的开源输入设备映射解决方案 【免费下载链接】QKeyMapper [按键映射工具] QKeyMapper,Qt开发Win10&Win11可用,不修改注册表、不需重新启动系统,可立即生效和停止。支持游戏手柄映射到键鼠&…

如何用Mate Engine打造你的免费开源虚拟桌面伴侣?终极指南来了!

如何用Mate Engine打造你的免费开源虚拟桌面伴侣?终极指南来了!

2026/7/12 12:04:44

如何用Mate Engine打造你的免费开源虚拟桌面伴侣?终极指南来了! 【免费下载链接】Mate-Engine A free Desktop Mate alternative with a lightweight interface and custom VRM support, though with more features. 项目地址: https://gitcode.com/gh…

MATLAB LQR控制完整工程包:含建模、仿真、GUI界面与可运行模型

MATLAB LQR控制完整工程包:含建模、仿真、GUI界面与可运行模型

2026/7/12 11:54:34

本文还有配套的精品资源,点击获取 简介:这个MATLAB资源包提供一套即装即用的LQR控制器实现方案,包含系统动力学建模脚本(xitongfangcheng.m)、状态反馈增益计算(LQR.m、LQR1.m)、Simulink动态…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/12 0:03:42

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/12 0:03:42

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/12 0:03:42

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/12 0:03:42

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/12 0:03:42

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/12 0:03:42

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…