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

「C/C++」C++11 之 智能指针

在这里插入图片描述

✨博客主页
何曾参静谧的博客
📌文章专栏
「C/C++」C/C++程序设计
📚全部专栏
「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合
「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发
「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明

目录

    • C++智能指针详解与注意事项
      • 一、智能指针概述
      • 二、智能指针详解
        • 1. std::unique_ptr
        • 2. std::shared_ptr
        • 3. std::weak_ptr
      • 三、使用智能指针的注意事项

C++智能指针详解与注意事项

在C++编程中,内存管理是一个至关重要的方面。手动管理内存不仅繁琐,而且容易出错,如内存泄漏、野指针等问题。为了解决这些问题,C++11引入了智能指针(Smart Pointers),它们能够自动管理内存,减少内存泄漏和悬挂指针的风险。本文将详细介绍C++中的几种主要智能指针及其使用注意事项。

一、智能指针概述

智能指针是封装了原始指针的类模板,通过RAII(Resource Acquisition Is Initialization)机制,在对象的生命周期结束时自动释放资源(主要是内存)。C++标准库提供了以下几种智能指针:

  1. std::unique_ptr:独占所有权的智能指针,同一时间只能有一个std::unique_ptr拥有某个资源。
  2. std::shared_ptr:共享所有权的智能指针,允许多个std::shared_ptr共享同一个资源,通过控制块管理资源的生命周期。
  3. std::weak_ptr:弱引用智能指针,不能独立拥有资源,必须与std::shared_ptr配合使用,解决循环引用问题。
  4. std::auto_ptr(已废弃):在C++11中被标记为废弃,并在C++17中被移除,不推荐使用。

二、智能指针详解

1. std::unique_ptr

std::unique_ptr是独占所有权的智能指针,它保证了同一时间只有一个std::unique_ptr实例可以拥有某个资源。当std::unique_ptr被销毁时,它所管理的资源也会被自动释放。

#include <memory>
#include <iostream>int main() {std::unique_ptr<int> ptr1 = std::make_unique<int>(10);// std::unique_ptr<int> ptr2 = ptr1; // 错误,不允许复制std::unique_ptr<int> ptr3 = std::move(ptr1); // 转移所有权if (!ptr1) {std::cout << "ptr1 is null\n";}// 释放所有权并手动管理内存  int* rawPtr = ptr3.release();  std::cout << "Value after release: " << *rawPtr << std::endl;  delete rawPtr; // 手动删除  std::cout << "Value: " << *ptr3 << "\n";return 0;
}

注意事项:

  • std::unique_ptr不支持复制,但支持移动语义。
  • 使用std::make_unique来创建std::unique_ptr,避免直接使用new
2. std::shared_ptr

std::shared_ptr是共享所有权的智能指针,允许多个std::shared_ptr实例共享同一个资源。当最后一个std::shared_ptr被销毁时,资源才会被释放。

#include <memory>
#include <iostream>int main() {std::shared_ptr<int> ptr1 = std::make_shared<int>(10);std::shared_ptr<int> ptr2 = ptr1; // 共享所有权std::cout << "Use count: " << ptr1.use_count() << "\n"; // 输出2return 0;
}

注意事项:

  • std::shared_ptr通过控制块(通常是一个隐藏的引用计数)来管理资源的生命周期。
  • 小心循环引用问题,可以使用std::weak_ptr来解决。
3. std::weak_ptr

std::weak_ptr是一种不控制资源生命周期的智能指针,它必须与std::shared_ptr一起使用,用于解决循环引用问题。

#include <memory>
#include <iostream>class B; // 前向声明class A {
public:std::shared_ptr<B> ptrB;~A() { std::cout << "A destroyed\n"; }
};class B {
public:std::weak_ptr<A> ptrA; // 使用weak_ptr避免循环引用~B() { std::cout << "B destroyed\n"; }
};int main() {std::shared_ptr<A> a = std::make_shared<A>();std::shared_ptr<B> b = std::make_shared<B>();a->ptrB = b;b->ptrA = a;return 0; // A和B都能正确销毁
}

注意事项:

  • std::weak_ptr不能独立拥有资源,必须从一个std::shared_ptr或另一个std::weak_ptr创建。
  • 使用std::weak_ptr::lock可以获取一个临时的std::shared_ptr,用于访问资源。

三、使用智能指针的注意事项

  1. 避免裸指针:尽量使用智能指针代替裸指针,减少手动管理内存的风险。
  2. 选择合适的智能指针:根据具体需求选择合适的智能指针类型,如独占资源使用std::unique_ptr,共享资源使用std::shared_ptr
  3. 避免循环引用:使用std::weak_ptr解决std::shared_ptr之间的循环引用问题。
  4. 注意性能:虽然智能指针简化了内存管理,但它们也引入了额外的开销(如引用计数)。在性能敏感的场景中,需要权衡使用智能指针的利弊。
  5. 避免不必要的复制:对于std::unique_ptr,使用std::move进行转移,避免不必要的复制操作。

通过合理使用智能指针,C++程序员可以更加高效地管理内存,减少内存泄漏和悬挂指针的风险,从而提高程序的稳定性和可靠性。


在这里插入图片描述

相关文章:

「C/C++」C++11 之 智能指针

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...

算法面试小抄

第一章:算法与数据结构要点速学 1.时间复杂度 (大 O) 首先&#xff0c;我们来谈谈常用操作的时间复杂度&#xff0c;按数据结构/算法划分。然后&#xff0c;我们将讨论给定输入大小的合理复杂性。 数组&#xff08;动态数组/列表&#xff09; 规定 n arr.length, 注意: &am…...

当有违法数据时,浏览器不解析,返回了undefined,导致数据不解析

现象&#xff1a;页面上没有看到数据 排查&#xff1a;断点到线上的源码里&#xff1a;1、协议回调确实没有拿到数据是个undefined 2、network里看服务确实响应了数据 3、控制台没有任何报错。 心情&#xff1a;莫名其妙的现象 我本地有json格式化工具&#xff0c;copy进去后&…...

在MySQL中ORDER BY使用的那种排序算法

在 MySQL 中&#xff0c;ORDER BY 子句的排序算法通常根据场景、数据量和表的索引情况而有所不同。MySQL 常用的排序算法包括&#xff1a; 文件排序&#xff08;File Sort&#xff09;&#xff1a;MySQL 没有使用索引排序的情况下&#xff0c;会进行文件排序&#xff0c;这可以…...

学习threejs,使用粒子实现雨滴特效

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.Points简介1.11 ☘️…...

分布式-单元化架构1

一 两地三中心 1.1 两地三中心* 两地指的是两个城市&#xff1a;同城&#xff0c;异地。三中心指的是三个数据中心&#xff1a;生产中心、同城容灾中心、异地容灾中心。 在同一个城市或者临近的城市建设两个相同的系统&#xff0c;双中心具备相当的业务处理能力&#xff0c;…...

C++模板、STL

目录 一、模板 1、函数模板 (1)、基本语法和使用 (2)、函数模板注意事项 (3)、普通函数与函数模板的区别 (4)、普通函数与函数模板的调用规则 (5)、模板的局限性 2、类模板 (1)、基本语法 (2)、类模板与函数模板区别 (3)、类模板中成员函数创建时机 (4)、类模板对象…...

计算机视觉中的点算子:从零开始构建

Hey小伙伴们&#xff01;今天我们要聊的是一个非常基础但极其重要的计算机视觉技术——点算子&#xff08;Point Operators&#xff09;。点算子主要用于对图像的每个像素进行独立的处理&#xff0c;比如亮度调整、对比度增强、灰度化等。通过这些简单的操作&#xff0c;我们可…...

国际中文教育知识图谱问答

你还在为毕业设计头疼么&#xff1f;想快速搭建一个智能化系统&#xff0c;展示数据又能精准回答问题&#xff1f;那你绝对不能错过这个超实用的 知识图谱问答系统&#xff0c;特别适用于需要整合复杂数据关系、交互性强的项目&#xff01; 这个系统基于 Neo4j图数据库 开发&a…...

酒店大板轻触开关与传统的开关有什么区别

酒店大板轻触开关与传统的开关在功能、设计、使用方式以及安装维护等多个方面都存在显著的差异。以下是对这些差异的详细分析&#xff1a; 功能差异 酒店大板轻触开关&#xff1a; 多功能性&#xff1a;酒店大板轻触开关通常集成了多种功能&#xff0c;如控制照明、窗帘、夜灯、…...

【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python电话号码 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python电话号码 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…...

对比两个json串的diff,支持map的深度递归

背景 项目重构&#xff0c;对老接口进行技术改造。动代码后&#xff0c;难免会有些bug&#xff0c;我们需要对比改造前后接口的返回&#xff0c;来判断逻辑是否有问题&#xff0c;这就涉及两个json的对比。 常规的diff文本工具是按行对比&#xff0c;无法处理复杂的map。本文通…...

【我的创作纪念日1024】

我的创作纪念日1024 机缘成就明年的规划 机缘 过去的1024个日子里&#xff0c;我在专业发展、职场和发展、科技创新创业、软件开发、人工智能、虚拟现实、区块链等栏目分享了一些工作和学习的建议和体会。尤其是在2022年&#xff0c;我连续发布100篇的博文&#xff0c;不仅仅是…...

萤石设备视频接入平台EasyCVR私有化视频平台变电站如何实现远程集中监控?

一、方案背景 随着城市经济的发展和电力系统的改造&#xff0c;变电站的数量和规模逐渐增加&#xff0c;对变电站的安全管理和监控需求也越来越高。视频监控系统作为重要的安全管理手段&#xff0c;在变电站中起到了关键的作用。 目前青犀视频研发的萤石设备视频接入平台EasyC…...

什么是多线程?请描述 Java 中实现多线程的基本方式?

今天和大家探讨一下 Java 中的多线程&#xff0c;包括它的基本概念、实现方式以及一些实际开发中的注意事项。 什么是多线程&#xff1f; 多线程是指在一个程序中存在多个执行流&#xff0c;每个执行流都可以独立于其他执行流执行。 在 Java 中&#xff0c;多线程允许开发者…...

Dynamic Sparse No Training: Training-Free Fine-tuning for Sparse LLMs

大语言模型&#xff08;LLM&#xff09;在设备上部署道路上落下了一个令人生畏的障碍。本文关注于大语言模型的剪枝算法。 动态稀疏训练&#xff08;Dynamic Sparse Training&#xff0c;DST&#xff09;是一种近期收到广泛关注的剪枝算法。与之前大部分剪枝方法需要训练整个网…...

解决n+1查询数据库问题

文章目录 1. 问题描述2. 解决方法3. 总结 1. 问题描述 在写项目中&#xff0c;可能会碰到一个问题&#xff1a;通过查询表A得到一个list结果&#xff0c;再对list中的n个元素各查询一次关联的表B。形成对数据库执行n1次查询。这种代码会无形增加数据库的处理负担&#xff0c;影…...

DICOM 基础知识:深入理解DICOM数据结构与标签说明

目录 DICOM 图像概念 DICOM 图像关键特性&#xff1a; DICOM 文件结构 常见数据元素&#xff1a; 数据元素示例详解 DICOM-VR 数据类型说明 DICOM 标准支持的数据集 结语 DICOM 图像概念 DICOM&#xff08;Digital Imaging and Communications in Medicine&…...

Git - 如何删除 push 过一次的文件链路追踪?

&#xff08;以 target 文件夹为例&#xff09;如果你已经在 .gitignore 中添加了 target/ 目录&#xff0c;但 target 文件夹仍然出现在 Git 的变更列表中&#xff0c;可能是因为它之前已经被添加到 Git 仓库中。即使你更新了 .gitignore&#xff0c;Git 仍然会跟踪这些文件。…...

软件测试学习总结

一.软件测试概念和目的 软件测试的概念: 测试模型(V模型) 软件测试就是在软件投入运行前,对软件需求分析、设计规格说明和编码实现的最终审查,它是软件质量保证的关键步骤。 通常对软件测试的定义有两种描述: 定义1:软件测试是为了发现错误而执行程序的过程 定义2:…...

c语言错题——#define对应的查找替换

文章目录 一、题目 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、题目 分析 结构体向最长的char对齐&#xff0c;前两个位段元素一共42位&#xff0c;不足8位&#xff0c;合起来占1字节&#xff0c;最后一个单独1字节&#xff0c;一共3字节。另外…...

Visual Basic介绍及简单例子

Visual Basic(简称 VB)是一种由微软公司开发的包含协助开发环境的事件驱动编程语言。 一、主要特点 易于学习和使用: Visual Basic 具有直观的可视化开发环境,使用户可以通过拖放控件和设置属性的方式快速创建用户界面。对于初学者来说,这种方式非常容易上手,无需深入了…...

Matlab学习01-矩阵

目录 一&#xff0c;矩阵的创建 1&#xff0c;直接输入法创建矩阵 2&#xff0c;利用M文件创建矩阵 3&#xff0c;利用其它文本编辑器创建矩阵 二&#xff0c;矩阵的拼接 1&#xff0c;基本拼接 1&#xff09; 水平方向的拼接 2&#xff09;垂直方向的拼接 3&#xf…...

【复旦微FM33 MCU 外设开发指南】外设篇1——硬件除法器

前言 本系列基于复旦微FM33LC0系列单片机的DataSheet编写&#xff0c;旨在提供一些开发指南。 本文章及本系列其他文章将持续更新&#xff0c;本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇 本文章最后更新日期&#xff1a;2024/10/24 文章目录 前言用途工作流…...

在元神操作系统启动时自动执行任务脚本

1. 背景 本文主要介绍让元神操作系统启动时自动执行任务脚本的方法&#xff0c;适用于无人化任务执行目的。将任务脚本及相关的应用程序准备好之后&#xff0c;把装有元神操作系统的U盘插入目标电脑&#xff0c;然后打开电脑电源就会自动完成所设置的任务。 2. 方法 &#x…...

JAVA学习-练习试用Java实现“判断是否为等边三角形的方法”

问题&#xff1a; 定义一个三角形类&#xff08;Triangle&#xff09;&#xff0c;包含三个边长&#xff08;a, b, c&#xff09;属性&#xff0c;并实现一个判断是否为等边三角形的方法。 解答思路&#xff1a; 下面是一个简单的 Triangle 类定义&#xff0c;其中包含了三个…...

Leetcode 140 Word Break II

题意&#xff1a;给定一个string以及一个wordDict,要求返回一个vector<string> &#xff0c;这个vector中的string都是word Dict中的组合 Input: s “catsanddog”, wordDict [“cat”,“cats”,“and”,“sand”,“dog”] Output: [“cats and dog”,“cat sand dog”…...

文理学院数据库应用技术实验报告0

文理学院数据库应用技术实验报告0 实验内容 打开cmd,利用MySQL命令连接MySQL服务器。 mysql -u root -p查看当前MySQL服务实例使用的字符集(character)。 SHOW VARIABLES LIKE character_set_server;查看当前MySQL服务实例支持的字符序(collation)。 SHOW VARIABLES LIKE c…...

Bootstrap 4 按钮

Bootstrap 4 按钮 Bootstrap 4 是一个流行的前端框架,它提供了大量的组件和样式,用于快速开发响应式和移动设备优先的网页。在本文中,我们将重点讨论 Bootstrap 4 中的按钮组件,包括它们的基本用法、样式选项和自定义方法。 基本按钮 在 Bootstrap 4 中,创建一个基本按…...

【笔记】LLM位置编码之标准位置编码

标准位置编码 起源原理证明&#xff1a;对于任何固定的偏移量 k k k&#xff0c; P E p o s k PE_{posk} PEposk​可以表示为 P E p o s PE_{pos} PEpos​的线性函数。计算 P E p o s k 与 P E p o s PE_{posk} 与PE_{pos} PEposk​与PEpos​的内积结论 通俗理解缺点 起源 由…...