当前位置: 首页 > web >正文

C++智能指针介绍和区别(std::unique_ptr、std::shared_ptr 和 std::weak_ptr)

在 C++ 中,std::unique_ptrstd::shared_ptrstd::weak_ptr智能指针(Smart Pointers),它们定义在 <memory> 头文件中,用于自动管理动态分配的内存资源,帮助开发者避免内存泄漏和手动 delete 指针带来的问题。

下面是这三种智能指针的简要介绍和区别:


1. std::unique_ptr

  • 独占所有权(Exclusive ownership)
  • 同一时间只能有一个 unique_ptr 指向某个资源。
  • 不能复制(拷贝构造函数和拷贝赋值运算符被删除),但可以移动(move)。
  • unique_ptr 被销毁时,它所管理的对象也会被自动删除。
示例:
std::unique_ptr<int> ptr1 = std::make_unique<int>(10);
// std::unique_ptr<int> ptr2 = ptr1; // 编译错误:不允许拷贝
std::unique_ptr<int> ptr2 = std::move(ptr1); // OK:转移所有权
使用场景:
  • 确保只有一个智能指针对资源拥有所有权。
  • 避免共享导致的复杂生命周期管理。

2. std::shared_ptr

  • 共享所有权(Shared ownership)
  • 多个 shared_ptr 可以指向同一个对象。
  • 内部使用引用计数(reference count),当最后一个 shared_ptr 被销毁时,资源才会释放。
  • 支持拷贝和赋值。
示例:
std::shared_ptr<int> ptr1 = std::make_shared<int>(20);
std::shared_ptr<int> ptr2 = ptr1; // OK:引用计数增加
使用场景:
  • 多个对象或模块需要共享一个资源。
  • 生命周期不确定,需自动管理。

3. std::weak_ptr

  • 弱引用(Weak reference)
  • 不拥有资源,也不影响资源的生命周期。
  • 必须与 shared_ptr 搭配使用,用来观察某个由 shared_ptr 管理的对象。
  • 用于解决循环引用问题(如 A 持有 B 的 shared_ptr,B 持有 A 的 shared_ptr)。
示例:
std::shared_ptr<int> shared = std::make_shared<int>(30);
std::weak_ptr<int> weakPtr = shared;if (auto spt = weakPtr.lock()) { // 获取临时 shared_ptrstd::cout << *spt << std::endl;
} else {std::cout << "对象已被释放" << std::endl;
}
使用场景:
  • 观察对象但不控制其生命周期。
  • 解决 shared_ptr 循环引用问题。

📊 总结对比表:

特性std::unique_ptrstd::shared_ptrstd::weak_ptr
所有权模型独占共享弱引用(无所有权)
是否可拷贝✅(但不会增加引用计数)
是否可移动
自动释放资源❌(需通过 lock() 获取 shared_ptr)
是否支持数组✅(C++17 起)✅(C++20 起推荐使用)✅(需配合 shared_ptr 使用)

✅ 推荐使用顺序(优先级):

  1. 优先使用 std::unique_ptr:最轻量、安全、高效。
  2. 如果确实需要共享所有权,使用 std::shared_ptr
  3. 若只是观察或打破循环依赖,使用 std::weak_ptr
http://www.xdnf.cn/news/10183.html

相关文章:

  • 004时装购物系统技术解析:构建智能时尚消费平台
  • PRECICE 工具介绍与使用示例
  • 7.atlas安装
  • 5.30 打卡
  • 【计算机网络】fork()+exec()创建新进程(僵尸进程及孤儿进程)
  • Day40
  • RFID赋能零件智能夹取新生态
  • 深度学习全面掌握指南
  • CMP401GSZ-REEL混合电压接口中的23ns延迟与±6V输入范围设计实现
  • 【Zephyr 系列 2】用 Zephyr 玩转 Arduino UNO / MEGA,实现串口通信与 CLI 命令交互
  • Vue 项目命名规范指南
  • 操作系统原理第9章 磁盘存储器管理 重点内容
  • JAVA:抽象类和接口
  • AI书签管理工具开发全记录(五):后端服务搭建与API实现
  • OSG编译wasm尝试
  • PostgreSQL部署
  • PyCharm接入DeepSeek,实现高效AI编程
  • Python中函数知识详解和示例
  • 正则化-深度学习
  • 2011肠衣问题
  • 视频压制(Video Encoding/Compression)
  • 20250530-C#知识:String与StringBuilder
  • dify账号与基础模型配置
  • RK3568项目(四)--uboot启动流程之启动模式选择
  • PPIO × AstrBot:多平台接入聊天机器人,开启高效协同 | 教程
  • 封装一个Qt调用动态库的类
  • LLM enhanced VRP
  • 根据面包屑的展开与隐藏控制样式
  • 告别充电焦虑:移动充电桩如何优化传统充电模式?
  • 湖北理元理律师事务所:债务优化服务的流程透明度建设