C++学习第二十八课:C++ 中的智能指针详解

在这里插入图片描述

在 C++ 中,内存管理是每个程序员都需要面对的问题。在处理动态分配的内存时,如果忘记释放内存,可能会导致内存泄漏。为了解决这个问题,C++11 引入了智能指针的概念。本文将详细介绍 C++ 中使用智能指针的方法,并结合实际案例进行讲解。

一、什么是智能指针

智能指针是一种对象,它可以像常规指针一样使用,但具有自动管理内存的功能。当智能指针离开其作用域时,它会自动删除所指向的对象,从而避免内存泄漏。C++11 提供了两种智能指针:std::unique_ptrstd::shared_ptr

二、std::unique_ptr 详解

std::unique_ptr 是一种独占所有权的智能指针,即同一时间只能有一个 std::unique_ptr 指向一个对象。当 std::unique_ptr 被销毁时,它会自动删除所指向的对象。

示例代码:

#include <iostream>
#include <memory>

class Test {
public:
    Test() { std::cout << "Test 构造函数" << std::endl; }
    ~Test() { std::cout << "Test 析构函数" << std::endl; }
};

int main() {
    std::unique_ptr<Test> ptr(new Test());
    // 当 ptr 离开作用域时,自动调用 Test 的析构函数
    return 0;
}

输出结果:

Test 构造函数
Test 析构函数

三、std::shared_ptr 详解

std::shared_ptr 是一种共享所有权的智能指针,即可以有多个 std::shared_ptr 指向同一个对象。当最后一个 std::shared_ptr 被销毁时,它会自动删除所指向的对象。

示例代码:

#include <iostream>
#include <memory>

class Test {
public:
    Test() { std::cout << "Test 构造函数" << std::endl; }
    ~Test() { std::cout << "Test 析构函数" << std::endl; }
};

int main() {
    {
        std::shared_ptr<Test> ptr1(new Test());
        std::shared_ptr<Test> ptr2 = ptr1;
        // 当 ptr1 和 ptr2 离开作用域时,自动调用 Test 的析构函数
    }
    return 0;
}

输出结果:

Test 构造函数
Test 析构函数

四、std::make_uniquestd::make_shared

为了更方便地创建智能指针,C++11 提供了 std::make_uniquestd::make_shared 函数。这两个函数可以简化智能指针的创建过程,并提高代码的可读性。

示例代码:

#include <iostream>
#include <memory>

class Test {
public:
    Test() { std::cout << "Test 构造函数" << std::endl; }
    ~Test() { std::cout << "Test 析构函数" << std::endl; }
};

int main() {
    // 使用 std::make_unique 创建 unique_ptr
    std::unique_ptr<Test> ptr1 = std::make_unique<Test>();
    // 使用 std::make_shared 创建 shared_ptr
    std::shared_ptr<Test> ptr2 = std::make_shared<Test>();
    return 0;
}

输出结果:

Test 构造函数
Test 构造函数

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

  1. 不要使用 delete 操作符删除智能指针所指向的对象,这会导致双重释放问题。
  2. 不要将原始指针(raw pointer)和智能指针混用,这可能导致内存泄漏或双重释放问题。
  3. 不要将两个 std::unique_ptr 赋值给同一个对象,这会导致所有权冲突。
  4. 不要将 std::unique_ptr 转换为 std::shared_ptr,这可能导致循环引用问题。

智能指针是C++中用于自动管理对象生命周期的工具,它们通过引用计数或其他机制来确保在不再需要时自动释放对象。以下是对智能指针类型的细致讲解:

  1. 深复制(Deep Copy)
  • 深复制是指在复制对象时,不仅复制对象的值,还复制对象所指向的内存内容。
  • 对于智能指针而言,深复制意味着创建一个新的动态分配的对象,并将原对象的内容复制到新对象中,然后让智能指针管理这个新的对象。
  • std::shared_ptrstd::unique_ptr 都支持深复制,因为它们都会创建一个新的动态分配的对象。
  1. 写时复制(Copy-on-Write, CoW)
  • 写时复制是一种优化策略,当多个智能指针共享同一个对象时,只有在其中一个智能指针试图修改对象时,才会进行实际的复制操作。
  • std::shared_ptr 使用写时复制机制来提高效率,在没有写入操作时,多个 shared_ptr 可以安全地共享同一个对象。
  1. 引用计数智能指针(Reference Counting Smart Pointers)
  • 引用计数智能指针通过维护一个引用计数来跟踪有多少个智能指针指向同一个对象。
  • std::shared_ptr 是一个引用计数智能指针,当最后一个 shared_ptr 被销毁时,它会自动释放所管理的对象。
  1. 引用链接智能指针(Reference Linking Smart Pointers)
  • 引用链接智能指针通常不直接管理对象的生命周期,而是通过观察其他智能指针来间接实现。
  • std::weak_ptr 是一种引用链接智能指针,它提供了一种方式来避免潜在的循环引用问题,但不会增加对象的引用计数。
  1. 破坏性复制(Disastrous Copy)
  • 破坏性复制并不是智能指针的一个标准概念,但可以理解为在复制过程中可能导致意外行为的情况。
  • 例如,当一个 shared_ptr 管理的资源被另一个 shared_ptr 或原始指针释放时,可能会导致悬挂指针或重复释放资源的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/613168.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

天龙怀旧游戏python脚本

设置图&#xff1a; 游戏窗口最大化。 海贼洞这里定位你要回点的定位。 运行bat就行&#xff0c;脚本出错了还是会重新运行脚本&#xff0c;运行自动启动&#xff0c;end暂停脚本&#xff0c;home重新启动脚本 1. 我常用的是内挂回点脚本&#xff0c; 下面都是前台脚本&…

(三)Appdesigner-界面转换及数据导入和保存

提示&#xff1a;文章为系列文章&#xff0c;可以在对应学习专栏里面进行学习。对应资源已上传 目录 前言 一、Appdesigner是什么&#xff1f; 二、界面切换 三、数据导入及保存 &#xff08;一&#xff09;数据导入 &#xff08;二&#xff09;数据保存 总结 前言 Appd…

windows设置Redis服务后台自启动

1.通过CMD命令行工是进入Redis安装目录&#xff0c;将Redis服务注册到 Windows服务中 redis-server.exe --service-install redis.windows.conf --loglevel verbose 2.查看—下Redis服务是否注册 WinR输入services.msc&#xff0c;确定进入&#xff0c;再查找是否有Redis 3.启动…

自动化测试基础 --- Jmeter

前置环境安装 首先我们需要知道如何下载Jmeter 这里贴上下载网站Apache JMeter - Download Apache JMeter 我们直接解压,然后在bin目录下找到jemter.bat即可启动使用 成功打开之后就是这个界面 每次打开可以用这种方式切换成简体中文 或者直接修改properties文件修改对应的语言…

C 语言中怎么产生真正的随机数?

在C语言中&#xff0c;要产生真正的随机数&#xff0c;我们通常使用标准库中的 <stdlib.h> 头文件中提供的随机数生成函数。 这些函数可以生成伪随机数&#xff0c;但它们在一定程度上是随机的&#xff0c;足以满足大多数应用程序的需求。 1. 伪随机数生成函数 C标准库…

《C语言文件处理:从新手到高手的跃迁》

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

【计算机毕设】基于SpringBoot的在线拍卖系统 - 免费源码(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 本项目旨在设计并实现一个基于Spring Boot的在线拍卖系统&#xff0c;为用户提供便捷的拍卖服务&#xff0c;实现商品的竞拍和交易功能&#xff0c…

前端 | 数据统计及页面数据展现

文章目录 &#x1f4da;实现效果&#x1f4da;模块实现解析&#x1f407;html&#x1f407;css&#x1f407;javascript &#x1f4da;实现效果 折线图分别展现当前累计单词总数及每篇新增单词数&#xff0c;鼠标悬浮读取具体数值。 数值统计 词云图展现&#xff0c;及点击查看…

在线旅游网站,基于 SpringBoot+Vue+MySQL 开发的前后端分离的在线旅游网站设计实现

目录 一. 前言 二. 功能模块 2.1. 登录界面 2.2. 管理员功能模块 2.3. 用户功能模块 三. 部分代码实现 四. 源码下载 一. 前言 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;旅游网站当然…

Error: Maximum response size reached

错误原因复现 请求下载的文件是4g的&#xff0c;postman报错Error: Maximum response size reached 解决办法 Postman设置请求时长和数据大小 Settings&#xff0c;打开设置面板 postman有默认请求时间&#xff0c;正常的postman请求后端少量数据&#xff0c;返回特别快。但…

美颜滤镜SDK解决方案,稳定可靠,易于集成

高质量的视觉体验已成为企业吸引用户、提升品牌形象的关键&#xff0c;美摄科技凭借其领先的美颜滤镜SDK技术&#xff0c;为企业提供了从人像美颜到多元场景处理的全方位解决方案&#xff0c;助力企业轻松实现视觉升级。 一、强大能力&#xff0c;覆盖多场景 美摄科技美颜滤镜…

洪水仿真模拟(ArcGIS),水利数字孪生新利器

这两天ArcGIS Pro的官方账号释放了一个名为“Flood Simulation in ArcGIS Pro”的洪水模拟功能视频。根据视频详情页的介绍&#xff0c;该洪水仿真模拟功能会作为新功能出现在ArcGIS Pro 3.3中。 由于我目前从事的主要应用方向都是弱GIS的领域&#xff0c;所以我已经很久没有再…

无线收发模块家电控制实验

zkhengyang可申请加入数字音频系统研究开发交流答疑群(课题组) 当然可以先用固定电平发送&#xff0c;可以实现&#xff0c;0/1数据发送&#xff0c;接收。 可以使用51单片机来编码码&#xff0c;解码&#xff0c;或者任何MCU或者SOC&#xff0c;DSP&#xff0c;FPGA。 注意G…

银河麒麟操作系统 v10 离线安装 Docker v20.10.9

1查看系统版本 [rootweb-0001 ~]# cat /etc/os-release NAME"Kylin Linux Advanced Server" VERSION"V10 (Tercel)" ID"kylin" VERSION_ID"V10" PRETTY_NAME"Kylin Linux Advanced Server V10 (Tercel)" ANSI_COLOR"…

OBS插件--自定义着色器

自定义着色器 自定义着色器是一个滤镜插件&#xff0c;可以用于源和场景。插件自带一百多款滤镜效果&#xff0c;支持自己编写效果代码。 下面截图演示下操作步骤&#xff1a; 首先&#xff0c;打开 OBS直播助手 在插件中心左侧导航栏&#xff0c;选择 滤镜 项&#xff0c;然…

在go-zero中使用jwt

gozero使用jwt 两个步骤 获取token验证token 前端获取token 先编写 jwt.api 文件&#xff0c;放在api目录下 syntax "v1"info (title: "type title here"desc: "type desc here"author: "type author here"email: &quo…

经常睡不好觉?试试用上华为手环9新升级的睡眠监测功能

睡眠问题是不是经常困扰着你呢&#xff1f;听说&#xff0c;华为手环9的睡眠监测功能升级了&#xff0c;无论是入睡前、睡眠中还是睡醒后&#xff0c;都能够帮助我们改善睡眠&#xff0c;让我们告别糟糕的睡眠质量&#xff01; 睡觉前&#xff0c;打开华为手环9的睡眠模式&…

二值信号量、计数型信号量与互斥量

二值信号量 什么是信号量? 信号量(Semaphore),是在多任务环境下使用的一种机制,是可以用来保证两个或多个关键代码段不被并发调用。 信号量这个名字,我们可以把它拆分来看,信号可以起到通知信号的作用,然后我们的量还可以用来表示资源的数量,当我们的量只有0和1的时…

1.基于python的单细胞数据预处理-特征选择

文章目录 特征选择背景基于基因离散度基于基因归一化方差基于基因皮尔森近似残差特征选择总结 参考&#xff1a; [1] https://github.com/Starlitnightly/single_cell_tutorial [2] https://github.com/theislab/single-cell-best-practices 特征选择背景 现在已经获得了经过…

企业微信集成H5授权登录相关知识(二)

流程&#xff1a; 1.前端请求企业微信获取code&#xff1a;官网网页授权链接 2.企业微信返回的code请求后端判断是否已绑定系统账户 3.后端根据企业微信code&#xff0c;accessToken获得userId 4.userId获取user进行oauth2授权方式进行免密登录 相关知识&#xff1a; 一&a…