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

【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.dtcms.com/a/336040.html

相关文章:

  • 05-实施任务控制
  • open Stack及VM虚拟机和其他平台虚拟机迁移至 VMware vSphere(esxi)虚拟化平台骨灰级后台磁盘替换法迁移方式
  • Maven依赖范围
  • C11期作业18(07.12)
  • 跨越南北的养老对话:为培养“银发中国”人才注入新动能
  • Linux——一些常用的其他命令
  • 学习Python中Selenium模块的基本用法(5:程序基本步骤)
  • MySQL数据库备份与恢复
  • 《棒球百科》奥运会取消了棒球·野球1号位
  • 旋钮键盘项目---foc讲解(闭环位置控制)
  • Redis-plus-plus API使用指南:通用操作与数据类型接口介绍
  • TensorFlow|张量流
  • C/C++复习(四)
  • 【LeetCode】单链表经典算法:移除元素,反转链表,约瑟夫环问题,找中间节点,分割链表
  • Javascript面试题及详细答案150道之(106-120)
  • 深度学习——常见的神经网络
  • Tomcat 类加载器原理深度解析
  • PowerPoint和WPS演示让多个对象通过动画同时出现
  • 近期(2021-2025)发行的常用国军标GJB 整理,2021,2022,2023,2024,2025
  • 深入理解QFlags:Qt中的位标志管理工具
  • 本文将详细介绍如何构建一个功能完整的键盘测试工具,包含虚拟键盘、实时统计、打字练习等核心功能,无需任何后端服务或复杂依赖。
  • 无人机视角土地区域类型识别分割数据集labelme格式4904张7类别
  • 使用oradebug收集数据库诊断信息
  • 第3章 Java NIO核心详解
  • AOP配置类自动注入
  • Linux系统分析 CPU 性能问题的工具汇总
  • 【102页PPT】某著名企业智能制造解决方案及智能工厂产品介绍(附下载方式)
  • 19.5 「4步压缩大模型:GPTQ量化实战让OPT-1.3B显存直降75%」
  • 微网智能光储协调控制器方案
  • 【运维进阶】实施任务控制