【C++】智能指针<shared_ptr>

C++ 智能指针unique_ptr、shared_ptr、weak_ptr详解(包含代码示例) 阅读详情

shared_ptr

#include<memory>

要确保用 new 动态分配的内存空间在程序的各条执行路径都能被释放是一件麻烦的事情。C++ 11 模板库的 头文件中定义的智能指针,即 shared _ptr 模板,就是用来部分解决这个问题的。

只要将 new 运算符返回的指针 p 交给一个 shared_ptr 对象“托管”,就不必担心在哪里写delete p语句——实际上根本不需要编写这条语句,托管 p 的 shared_ptr 对象在消亡时会自动执行delete p。而且,该 shared_ptr 对象能像指针 p —样使用,即假设托管 p 的 shared_ptr 对象叫作 ptr,那么 *ptr 就是 p 指向的对象。


通过 shared_ptr 的构造函数,可以让 shared_ptr 对象托管一个 new 运算符返回的指针,写法如下:

C++
shared_ptr<T> ptr(new T); // T 可以是 int、char、类等各种类型

此后,ptr 就可以像 T* 类型的指针一样使用,即 *ptr 就是用 new 动态分配的那个对象。

多个 shared_ptr 对象可以共同托管一个指针 p,当所有曾经托管 p 的 shared_ptr 对象都解除了对其的托管时,就会执行delete p。

例如下面的程序

C++
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
    int i;
    A(int n):i(n) { };
    ~A() { cout << i << " " << "destructed" << endl; }
};
int main()
{
    shared_ptr<A> sp1(new A(2)); //A(2)由sp1托管,
    shared_ptr<A> sp2(sp1);       //A(2)同时交由sp2托管
    shared_ptr<A> sp3;
    sp3 = sp2;   //A(2)同时交由sp3托管
    cout << sp1->i << "," << sp2->i <<"," << sp3->i << endl;
    A * p = sp3.get();      // get返回托管的指针,p 指向 A(2)
    cout << p->i << endl;  //输出 2
    sp1.reset(new A(3));    // reset导致托管新的指针, 此时sp1托管A(3)
    sp2.reset(new A(4));    // sp2托管A(4)
    cout << sp1->i << endl; //输出 3
    sp3.reset(new A(5));    // sp3托管A(5),A(2)无人托管,被delete
    cout << "end" << endl;
    return 0;
}

程序的输出结果如下:
2,2,2
2
3
2 destructed
end
5 destructed
4 destructed
3 destructed

可以用第 14 行及第 16 行的形式让多个 sharecLptr 对象托管同一个指针。这多个 shared_ptr 对象会共享一个对共同托管的指针的“托管计数”。有 n 个 shared_ptr 对象托管同一个指针 p,则 p 的托管计数就是 n。当一个指针的托管计数减为 0 时,该指针会被释放。shared_ptr 对象消亡或托管了新的指针,都会导致其原托管指针的托管计数减 1。

第 20、21 行,shared_ptr 的 reset 成员函数可以使得对象解除对原托管指针的托管(如果有的话),并托管新的指针。原指针的托管计数会减 1。

输出的第 4 行说明,用 new 创建的动态对象 A(2) 被释放了。程序中没有写 delete 语句,而 A(2) 被释放,是因为程序的第 23 行执行后,已经没有 shared_ptr 对象托管 A(2),于是 A(2) 的托管计数变为 0。最后一个解除对 A(2) 托管的 shared_ptr 对象会释放 A(2)。

main 函数结束时,sp1、sp2、sp3 对象消亡,各自将其托管的指针的托管计数减为 0,并且释放其托管的指针,于是会有以下输出:

5 destructed
4 destructed
3 destructed

只有指向动态分配的对象的指针才能交给 shared_ptr 对象托管。将指向普通局部变量、全局变量的指针交给 shared_ptr 托管,编译时不会有问题,但程序运行时会出错,因为不能析构一个并没有指向动态分配的内存空间的指针。

注意,不能用下面的方式使得两个 shared_ptr 对象托管同一个指针:

C++
A* p = new A(10);
shared_ptr <A> sp1(p), sp2(p);

sp1 和 sp2 并不会共享同一个对 p 的托管计数,而是各自将对 p 的托管计数都记为 1(sp2 无法知道 p 已经被 sp1 托管过)。这样,当 sp1 消亡时要析构 p,sp2 消亡时要再次析构 p,这会导致程序崩溃。

C++智能指针shared_ptr的原理与实现 shared_ptr 是 C++ 标准库提供的一个智能指针类,它的原理基于引用计数(reference counting)。当我们使用 shared_ptr 管理一个对象时,实际上会有一个额外的数据结构来维护引用计数信息。这个计数器会记录有多少个 shared_ptr 实例共享同一个指针对象。在创建 shared_ptr 对象时,引用计数会初始化为 1。 阅读详情

相关推荐

【C++】share_ptr详解

分析:根据对象生成顺序,先初始化基类 enable_shared_from_this ,再初始化派生类 Frame 对象本身,这时 Frame 对象已经生成,但 _M_weak_this 成员还未被初始化,最后应通过 shared_ptr<T> sp(new T()) 等方式调用 shared_ptr 构造函数(内部会调用 _M_weak_assign 成员函数来初始化 _M_weak_this 成员)。share_ptr 内部中的引用计数是线程安全的,但是引用的资源不是线程安全的。

songbijian的博客 6390

C++11 shared_ptr(智能指针)详解

要确保用 new 动态分配的内存空间在程序的各条执行路径都能被释放是一件麻烦的事情。C++11 模板库的 <memory> 头文件中定义的智能指针,即 shared _ptr 模板,就是用来部分解决这个问题的。 只要将 new 运算符返回的指针 p 交给一个 shared_ptr 对象“托管”,就不必担心在哪里写delete p语句——实际上根本不需要编写这条语句,托管 p 的 shared_ptr 对象在消亡时会自动执行delete p。而且,该 shared_ptr 对象能像指针 p —样.

Android 系统开发 351

C++11智能指针(unique_ptr、shared_ptr、weak_ptr)

更多文章欢迎访问 程序员小非 博客 很多人怕写C/C++ 程序就是因为指针,因为指针给了程序员高度的自由,同样也赋予了高度的责任,稍有不慎就导致内存泄漏。其实写C++ 可以完全不用指针,尤其C++ 11对智能指针作了进一步的升级,在不需要使用任何裸指针的前提下也可以写出高效的C++ 程序。C++ 11中定义了unique_ptr、shared_ptr与weak_ptr三种智能指针(smart ...

~码农小非~的专栏 1万+

C++智能指针shared_ptr讲解与使用

手动管理的弊端 在简单的程序中,我们不大可能忘记释放 new 出来的指针,但是随着程序规模的增大,我们忘了 delete 的概率也随之增大。在 C++ 中 new 出来的指针,赋值意味着引用的传递,当赋值运算符同时展现出“值拷贝”和“引用传递”两种截然不同的语义时,就很容易导致“内存泄漏”。 手动管理内存带来的更严重的问题是,内存究竟要由谁来分配和释放呢?指针的赋值将同一对象的引用散播到程序各处,...

李政的博客 1万+

C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

详细讲解C++11中引入的智能指针unique_ptr、shared_ptr和weak_ptr。

dvlinker的技术专栏 3万+

国产机载操作系统天脉ACoreOS实战:从零搭建开发环境到应用移植

本文详细介绍了国产机载操作系统天脉ACoreOS的实战开发流程,从核心特性解析到开发环境搭建,再到VxWorks应用移植策略。重点阐述了其符合ARINC 653标准的时空分区架构如何保障高可靠性,并提供了从零创建分区工程、重构通信与任务代码的具体步骤,为开发者向这一国产化平台迁移提供了实用指南。

flower的专栏 633

C++(标准库):04---智能指针之shared_ptr

一、shared_ptr类 头文件:#include<memory> 智能指针,是一个模板。创建智能指针时,必须提供指针所指的类型 如果当做提条件判断,则是检测其是否为空 shared_ptr<string> p1; //指向string shared_ptr<list<int>> p2;//指向int的list if(p1 &...

董哥的黑板报 2240

C++智能指针详解:shared_ptr

C++没有内存回收机制,每次程序员new出来的对象需要手动delete,流程复杂时可能会漏掉delete,导致内存泄漏。于是C++引入智能指针,可用于动态资源管理,资源即对象的管理策略。 使用 raw pointer 管理动态内存时,经常会遇到这样的问题: 忘记delete内存,造成内存泄露。 出现异常时,不会执行delete,造成内存泄露。 下面的代码解释了,当一个操作发生异常时,会导致delete不会被执行: void func() { auto ptr = new Widget;

feikudai8460的博客 1万+

Unity类银河战士恶魔城学习总结(P162 Improve skeleton提升敌人的效果)

为敌人添加了快慢刀

suzh1qian的博客 572

高云FPGA系列教程(7):ARM GPIO外部中断

高云GN1NSR-4C共有16个GPIO,每个GPIO可配置成输入或输出模式,支持中断输入,触发方式可选择:上升沿、下降沿、高电平、低电平触发。中断优先级可通过NVIC进行设置,支持 0-7 级可编程中断优先级。

whik1194的博客 1375

C++11的智能指针shared_ptr、weak_ptr源码解析

C++智能指针shared_ptr源码解析1、前言2、源码准备3、智能指针概念4、源码解析4.1、shared_ptr解析4.1.1、shared_ptr4.1.2、__shared_ptr4.1.3、__shared_count4.1.4、_Sp_counted_base4.1.5、_Sp_counted_ptr 1、前言 本文仅对C++智能指针shared_ptr、weak_ptr源码进行解析,需要读者有一定的C++基础并且对智能指针有所了解,但是本文不对智能指针的使用方法、使用场景、效率等方面进行阐述

游戏行业资深搬砖人员 1万+

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统(深度学习模型+UI界面+训练数据集)

随着人工智能技术在农业领域的深入应用,基于深度学习的害虫检测系统已成为智慧农业的重要组成部分。本文详细介绍了一种基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统,涵盖算法原理、数据集构建、模型训练、系统实现及完整代码。该系统能够实时检测并识别多种农作物害虫,为农业生产提供精准的病虫害监测解决方案。

YOLO 273

C++_智能指针shared_ptr和weak_ptr

智能指针的本质是一个模板类,内部封装了指针变量和一些方法. 智能指针的原理是创建一个模板类对象并将其压入栈中,然后将new申请的堆内存指针(原始指针)"委托"给智能指针,当智能指针超出其作用域要释放时,系统自动调用智能指针的析构函数(内部有释放原始指针的一系列代码),从而将原始指针指向的内存自动释放,不再需要程序员手动释放,极大地减少了内存泄漏和野指针的问题,很nice.

qq_74224788的博客 1924

拉曼光谱入门:10.显微拉曼与共聚焦技术

本文系统阐述了显微拉曼光谱技术与共聚焦原理的融合机制,详细解析了从激光激发、针孔空间滤波到光谱采集的完整光路架构,阐明了共聚焦设计在提升三维空间分辨率、抑制荧光背景及实现微区无损层析方面的核心优势,并探讨了关键光学器件的性能边界与系统技术局限。

qq_53529450的博客 167

Euro-NCAP-HWA测试流程中文版V1.1(2023发布)

在本协议中,使用了以下术语:Vehicle undertest (VUT) – 指根据本规程测试的车辆,车上有碰撞前的碰撞缓解或避免系统Global VehicleTarget (GVT) – 指本协议中使用的车辆目标,其定义见TB025—Euro-NCAP全球车辆目标规范v1.0辅助其他车辆(SOV)--指最新的 AEB VRU 测试规程中定义的 "大型障碍车辆"(而非机器人控制的平台),用于本规程中的 "切出 "测试。Time To Collision (TTC) – 指在VUT碰撞GVT之前的剩余时间

小明师兄的博客 596

【C++】智能指针——auto_ptr,unique_ptr,shared_ptr

1.智能指针对象中引用计数是多个智能指针对象共享的,两个线程中智能指针的引用计数同时 ++或--,这个操作不是原子的,引用计数原来是1,++了两次,可能还是2.这样引用计数就错 乱了。旧的智能指针的会转移给新的智能指针,而旧的智能指针的会被置空。解决方案:在引用计数的场景下,把节点中的_prev和_next改成weak_ptr就可以了,weak_ptr不会增加引用计数,代码示意。该问题是有类似于链表节点的结构引起的,当外部的智能指针都释放了,就拿不内部的智能指针,那么节点就不会释放。使用方法参考官方文档。

2301_79796701的博客 1842

点云统计滤波 (python详细过程版)【2025最新版】

统计滤波python详细过程版,博客长期更新,本文最近更新时间为:2025年1月12日。

点云侠的博客 5638

【c++】智能指针(auto_ptr, unique_ptr, shared_ptr, weak_ptr)

前言 一、为什么需要智能指针 二、智能指针 RAII 像指针一样使用 三、auto_ptr 概念讲解 模拟实现 测试 四、unique_ptr 概念讲解 模拟实现 测试 五、shared_ptr 概念讲解 模拟实现 测试 六、shared_ptr的循环引用 场景引入 如何解决循环引用问题 七、weak_ptr 概念讲解 模拟实现 测试 八、shared_ptr的定制删除器 概念讲解 模拟实现 测试一 测试二 测试三 测试四 九、智能指针的总结 十、内存泄漏 概念讲解 内存泄漏分类 如何检测内存泄漏 如何避免

重铸自身根基的博客 1622

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【c++11 篇】智能指针-shared_ptr

智能指针产生原因:c++中不像java 自带垃圾回收机制,必须释放掉分配的内存,否则就会造成内存泄露。因此c++11引入了智能指针。智能指针是存储指向动态分配(堆)对象指针的类,用于生存期的控制,能够确保在离开指针所在作用域时,自动的销毁分配的对象,防止内存泄露。原理:智能指针的核心实现技术是引用计数,每使用它一次内部引用计数加1,每析构一次内部引用计数减1,减为0时,删除原始指针指向的堆区内存使用智能指针需要引用头文件<memory>。sharedptr共享的智能指针u。

2401_85061293的博客 863

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【C++】shared_ptr共享型智能指针详解

指针是C/C++区别于其他语言的最强大的语法特性,借助指针,C/C++可以直接操纵内存内容。但是,指针的引入也带来了一些使用上的困难,这要求程序员自己必须手动地对分配申请的内存区进行管理。 本文实例源码github地址:https://github.com/yngzMiao/yngzmiao-blogs/tree/master/2020Q2/20200427。 shared_ptr基本用法 智能...

Yngz_Miao的博客 3万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C++智能指针的使用,auto_ptr,unique_ptr,shared_ptr,weak_ptr详解

C++智能指针的用法,auto_ptr,unique_ptr,shared_ptr,weak_ptr

liu20000505的博客 2313

C++智能指针1——shared_ptr类

在C++中,动态内存的管理是通过一对运算符来完成的:动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极其困难的。有时我们会忘记释放内存,在这种情况下就会产生内存泄漏;有时在尚有指针引用内存的情况下我们就释放了它,在这种情况下就会产生引用非法内存的指针。为了更容易(同时也更安全)地使用动态内存,新的标准库提供了两种智能指针类型来管理动态对象。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。新标准库提供的这两种智能指针的区别在于管理底层指针的方式这三种类型都定义在memory头文件

2301_80224556的博客 1227

C++智能指针 shared_ptr 和 unique_ptr

传统C/C++编程中,使用new或者malloc动态申请内存后,必须手动调用delete或者free去释放,否则就会造成内存泄漏。在C++ 11语法中,提供了智能指针来管理内存,开发者不必再关心内存的释放问题,智能指针可以自动去释放管理的内存空间。

new9232的博客 1459

C++智能指针unique_ptr与shared_ptr

文章目录1.unique_ptr特点2.unique_ptr例子3.unique_ptr总结4.shared_ptr特点5.shared_ptr例子6.shared_ptr中的自定义删除器 Deleter7.shared_ptr 相对于普通指针的优缺点 1.unique_ptr特点 unique_ptr 是 C++ 11 提供的用于防止内存泄漏的智能指针中的一种实现,独享被管理对象指针所有权的智能指针。 unique_ptr对象包装一个原始指针,并负责其生命周期。当该对象被销毁时,会在其析构函数中删除关联

喜欢打篮球的普通人 7014

C++智能指针之shared_ptr

在C++中,动态内存的申请和释放是通过运算符:new 和 delete 进行管理的。其中 new 负责申请内存,delete负责释放内存。动态内存的使用很容易出现问题,这主要在于你需要保证在正确的时间释放内存,这是比较困难的,如果你忘记释放内存,就会造成内存泄露;有时在还有指针引用内存的情况下我们就释放了它,在这种情况下就会产生引用非法内存的指针。

CltCj的博客 7908
上一篇: 【WIN】【C/C++】获取文件版本号
下一篇: 【Qt】QTreeWidget设置自动列宽
欧恩意
博客等级 码龄7年 677粉丝 138原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧恩意

如有帮助,感谢打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值