C++ 智能指针详解:从原理到实践

简介: 深入解析 C++ 智能指针的原理与用法,掌握 unique_ptr、shared_ptr、weak_ptr 的最佳实践

C++ 智能指针详解:从原理到实践

在现代 C++ 开发中,智能指针是内存管理的核心工具,它们帮助我们避免内存泄漏和悬空指针问题。

为什么需要智能指针?

传统的裸指针存在诸多问题:

void problematic() {
   
    int* ptr = new int(42);
    // 如果这里抛出异常,内存泄漏!
    doSomething();
    delete ptr;  // 可能永远执行不到
}

三种智能指针

unique_ptr:独占所有权

unique_ptr 确保同一时间只有一个指针拥有资源:

#include <memory>

auto ptr = std::make_unique<int>(42);
// std::unique_ptr<int> ptr2 = ptr;  // 编译错误!
std::unique_ptr<int> ptr2 = std::move(ptr);  // 转移所有权

使用场景:工厂函数返回值、类成员独占资源

shared_ptr:共享所有权

多个指针可共享同一资源,引用计数归零时自动释放:

auto sp1 = std::make_shared<std::string>("Hello");
auto sp2 = sp1;  // 引用计数 = 2

std::cout << sp1.use_count() << std::endl;  // 输出: 2

注意:避免循环引用!

weak_ptr:打破循环引用

weak_ptrshared_ptr 的观察者,不增加引用计数:

class Node {
   
public:
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> prev;  // 使用 weak_ptr 避免循环引用
};

性能对比

特性 unique_ptr shared_ptr weak_ptr
开销 零开销 引用计数 引用计数
拷贝 不可拷贝 可拷贝 可拷贝
线程安全 计数安全 计数安全

最佳实践

  1. 优先使用 make_unique/make_shared

    // 推荐
    auto ptr = std::make_unique<Widget>();
    // 不推荐
    std::unique_ptr<Widget> ptr(new Widget());
    
  2. 函数参数传递

    void process(Widget* w);           // 不转移所有权
    void consume(std::unique_ptr<Widget> w);  // 转移所有权
    

总结

智能指针是现代 C++ 的基石。合理选择 unique_ptrshared_ptrweak_ptr,能让代码更安全、更易维护。

相关文章
|
8月前
|
存储 安全 定位技术
交友APP开发搭建/社交软件同城交友推荐匹配
打造社交APP最小可行产品(MVP):支持手机号/微信登录,完善个人资料与兴趣标签。核心匹配采用滑动交友、问卷配对及兴趣群组模式,双向匹配后可聊天。集成腾讯云IM、地图、云存储、短信验证等第三方服务,快速部署上线。通过冷启动运营获取种子用户,结合活动与数据驱动持续迭代优化。
1361 1
交友APP开发搭建/社交软件同城交友推荐匹配
|
关系型数据库 MySQL 数据库
MySQL数据库期末项目 图书馆管理系统(上)
MySQL数据库期末项目 图书馆管理系统
1256 0
|
JavaScript 前端开发
el-upload上传文件
el-upload上传文件
1625 0
|
Prometheus 监控 Cloud Native
【监控利器Prometheus】——Prometheus+Grafana监控SpringBoot项目JVM信息
Prometheus+Grafana监控SpringBoot项目JVM信息 1. SpringBoot项目配置JVM采集 2. Prometheus配置 3. 配置grafana 4. 扩展-通过JMX Exporter监控JVM信息
【监控利器Prometheus】——Prometheus+Grafana监控SpringBoot项目JVM信息
|
4月前
|
存储 人工智能 Java
告别 AI 对话 “失忆”!Spring AI 聊天记忆底层原理与全场景落地实战
Spring AI提供优雅的聊天记忆解决方案,彻底解决大模型“失忆”痛点。其分层架构支持内存/MySQL等多存储,通过ChatMemory、ChatMemoryRepository和ChatMemoryAdvisor三大组件,实现会话隔离、消息有序、窗口可控,开箱即用,低侵入、高扩展。
898 13
告别 AI 对话 “失忆”!Spring AI 聊天记忆底层原理与全场景落地实战
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
|
存储 算法 C++
【C++核心】结构体、共用体详解
这篇文章详细讲解了C++中结构体和共用体的概念、定义、使用场景和案例,包括结构体的创建、数组、指针、嵌套、函数参数传递,以及共用体的特点和应用实例。
463 4
|
关系型数据库 MySQL 数据库
navicat 查看,设计并导出数据库 ER图
navicat 查看,设计并导出数据库 ER图
5376 5
|
JavaScript Java 云计算
后端开发的演变与未来趋势
在数字化时代的浪潮中,后端开发扮演着至关重要的角色。本文将探讨后端技术的历史演变、当前主流技术和框架、以及面临的挑战和未来的发展趋势。通过深入浅出的方式,为读者揭示后端开发的奥秘,并启发对未来技术的思考。
|
Linux 网络安全 数据安全/隐私保护
使用宝塔Linux搭建DVWA靶场保姆级教程
这是一篇详细的教程,作者基于其在Web渗透测试领域的学习经验,利用宝塔Linux面板搭建了DVWA靶场。从安装Linux宝塔面板到通过Docker运行DVWA容器,每一步都有详尽的文字描述和配图指导,确保读者能够顺利地进行实践操作,非常适合初学者快速上手并掌握相关技能。
1334 1