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

【C++知识杂记1】智能指针及其分类

智能指针(smart pointer) 是 C++11 引入的一类 模板类,用来封装原始指针,自动管理堆内存的生命周期,避免出现 内存泄漏悬空指针(野指针) 的问题。

当智能指针对象离开作用域时,它会自动调用 delete 来释放所管理的资源,从而实现 RAII(资源获取即初始化,Resource Acquisition Is Initialization) 思想。


🧠 智能指针的种类

C++ 标准库(<memory> 头文件)提供了三种主要的智能指针:


1. std::unique_ptr(独占智能指针)

  • 特点:独占式所有权,一个资源只能由一个 unique_ptr 拥有。
  • 拷贝:不允许拷贝,只能通过 std::move 转移所有权。
  • 适用场景:对象的生命周期和作用域绑定,保证同一时间只有一个所有者。
  • 创建方式:推荐使用 std::make_unique<T>()(C++14 以后)。

示例:

#include <memory>
#include <iostream>
using namespace std;int main() {auto p = std::make_unique<int>(42);cout << *p << endl;  // 输出 42auto q = std::move(p); // 转移所有权if (!p) cout << "p is empty\n"; // p 已经不再管理对象
}

2. std::shared_ptr(共享智能指针)

  • 特点:共享式所有权,多个 shared_ptr 可以指向同一资源。
  • 内存释放:内部维护一个 引用计数,当最后一个 shared_ptr 被销毁时,才调用 delete 释放资源。
  • 适用场景:多个对象或函数需要共享同一个动态分配的对象。
  • 创建方式:推荐使用 std::make_shared<T>()

示例:

#include <memory>
#include <iostream>
using namespace std;int main() {auto p1 = std::make_shared<int>(42);auto p2 = p1;  // 引用计数 +1cout << "use_count = " << p1.use_count() << endl; // 2p1.reset(); // p1 不再持有对象cout << "use_count = " << p2.use_count() << endl; // 1
}

⚠️ 注意:shared_ptr 可能导致 循环引用问题(两个对象互相持有 shared_ptr,导致引用计数无法归零)。


3. std::weak_ptr(弱引用智能指针)

  • 特点:一种 弱引用,用于配合 shared_ptr 使用,不增加引用计数。
  • 适用场景:打破 shared_ptr 的循环引用。
  • 使用方式:不能直接访问资源,必须先调用 .lock() 获得一个 shared_ptr

示例:

#include <memory>
#include <iostream>
using namespace std;int main() {auto sp = std::make_shared<int>(42);std::weak_ptr<int> wp = sp;  // 弱引用if (auto temp = wp.lock()) { // 转换为 shared_ptrcout << *temp << endl;   // 42}
}

📌 小结

智能指针所有权拷贝释放时机适用场景
unique_ptr独占❌ 禁止拷贝,✔️ 允许 std::move作用域结束时对象唯一所有者
shared_ptr共享✔️ 允许拷贝引用计数归零时多个对象共享同一资源
weak_ptr无(弱引用)✔️ 允许拷贝不影响对象释放辅助 shared_ptr,解决循环引用
http://www.xdnf.cn/news/18044.html

相关文章:

  • w嵌入式分享合集68
  • 什么是EDA(Exploratory Data Analysis,探索性数据分析)
  • MariaDB 多源复制
  • Windchill 11 Enumerated Type Customization Utility-枚举类型自定义实用程序
  • 嵌入式开发入门—电子元器件~半导体
  • Linux设备模型深度解析
  • 运动场和光流-动手学计算机视觉17
  • Spring 源码学习(十一)—— webmvc 配置
  • 【k8s、docker】Headless Service(无头服务)
  • Tomcat Connector连接器原理
  • 阶段二:7-上网行为安全概述
  • Spring Boot 项目配置 MySQL SSL 加密访问
  • SQL详细语法教程(四)约束和多表查询
  • 智能汽车领域研发,复用云原始开发范式?
  • 开源数据发现平台:Amundsen Search Service 搜索服务
  • SparkSQL性能优化实践指南
  • gRPC网络模型详解
  • 从0开始学习Java+AI知识点总结-17.web基础知识(数据库)
  • ARM汇编代码新手入门
  • 【人工智能99问】残差链接是什么,是如何起作用的?(28/99)
  • C语言相关简单数据结构:双向链表
  • 影刀 RAP 迁移华为云备忘录数据到得到笔记
  • C++编程实战:高效解决算法与数据结构问题
  • Python多线程、锁、多进程、异步编程
  • 自动驾驶中的传感器技术34——Lidar(9)
  • Python训练营打卡Day35-复习日
  • 2025年5月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(五)
  • Pandas 和 NumPy的区别和联系
  • 安卓开发中遇到Medium Phone API 36.0 is already running as process XXX.
  • RK3568平台开发系列讲解:PCIE trainning失败怎么办