Boost智能指针:shared_ptr

C++ 智能指针(共享指针、唯一指针、自动指针) 1. 概述 当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝;另一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。 智能指针是存储指向动态分配对象指针的类。除了能够在适当的时间自动删除指向的对象外,他们的工作机制很像C++的内置指针。从较浅的层面看,智能指针是利用了一种叫做RAII(资源获取即初始化)的技术对普通的指针进行封装,这使得智能指针实质是一个对象,行为表现的却像一个指针。智能指针在面对... 阅读详情
  共享指针 ( shared_ptr) 是现在的 Boost 库中提供的,并且应该是将来 C++1x 的标准库中提供的一个模板类。在此之前,ISO/IEC 14882:2003 标准库 <memory> 中的“自动指针 (auto_ptr)”也有类似的功能。显然 shared_ptr 要比 auto_ptr 从功能上来说应该强大一些。这篇文章主要介绍 shared_ptr 的最基本用法和注意事项,相当于入门级多一点点。

1. shared_ptr 的功能

shared_ptr 主要的功能是,管理动态创建的对象的销毁。它的基本原理就是记录对象被引用的次数,当引用次数为 0 的时候,也就是最后一个指向某对象的共享指针析构的时候,共享指针的析构函数就把指向的内存区域释放掉。

共享指针对象重载了 operator* 和 operator-> , 所以你可以像通常的指针一样使用它。这部分不再赘述。

2. shared_ptr 所在库

2.1. 对于 Visual C++ 2010

目前,Visual C++ 2010 的 <memory> 库里,已经包含了 shared_ptr 模板类,也就是说,你可以直接这样写:

#include <memory>

2.2. 对于其它支持 ISO/IEC 14882:2003 标准的编译器

而 GNU G++ 的标准库中还没有支持(毕竟是将来的标准),如果在 G++ 中想使用 shared_ptr, 还是得用到 Boost 库,就是说,在 G++ 里,你得这样写:

#include <boost/shared_ptr.hpp>

3. shared_ptr 的构造

保险起见,你应该仅从以下几种途径构造一个共享指针(以下例子中若没特殊说明,T 就代表共享指针所指向的对象的类型):

3.0. 使用空参数构造函数构造

也就是说,你可以直接定义一个 shared_ptr 而不指定构造函数的内容:

1
shared_ptr <T > ptr ;

这样做的话,ptr 的意义就相当于一个 NULL 指针。当你试图在一个空指针上做类似于 *ptr 或者 ptr->xx 之类的东西的时候,应该会收到异常的。

3.1. 直接从 new 操作符的返回值构造

用代码来表示,就是可以这样使用:

1
shared_ptr <T > ptr ( new T ( ) ) ;

3.2. 使用复制构造函数(或等号重载),从其它 shared_ptr 的对象构造

一种显然的情况是这样的:

1
2
shared_ptr <T > ptr1 ( new T ( ) ) ; // 本行与 3.1. 中的构造方法是一样的
shared_ptr <T > ptr2 (ptr1 ) ;     // 这就是使用复制构造函数的方法,会让引用计数加 1

还有,shared_ptr 可以当作函数的参数传递,或者当作函数的返回值返回,这个时候其实也相当于使用复制构造函数。

3.3. 从 shared_ptr 提供的类型转换 (cast) 函数的返回值构造

shared_ptr 也可以类型转换,有关类型转换的详情参见下面的 5. 此处假设 B 是 A 的子类,那么,在 C 语言中 B 的指针当然是可以转换成 A 的指针的。在共享指针里,应该这样做:

1
2
shared_ptr <B > ptrb ( new B ( ) ) ;
shared_ptr <A > ptra ( dynamic_pointer_cast <A > (ptrb ) ) ;

4. shared_ptr 的“赋值”

shared_ptr 也可以直接赋值,但是必须是赋给相同类型的 shared_ptr 对象,而不能是普通的 C 指针或 new 运算符的返回值。当共享指针 a 被赋值成 b 的时候,如果 a 原来是 NULL, 那么直接让 a 等于 b 并且让它们指向的东西的引用计数加 1; 如果 a 原来也指向某些东西的时候,如果 a 被赋值成 b, 那么原来 a 指向的东西的引用计数被减 1, 而新指向的对象的引用计数加 1. 就是说以下代码是允许的:

1
2
3
shared_ptr <T > a ( new T ( ) ) ;
shared_ptr <T > b ( new T ( ) ) ;
a = b ; // 此后 a 原先所指的对象会被销毁,b 所指的对象引用计数加 1

shared_ptr 的对象在构造之后,可以被赋予空值,此时使用的应该是 reset() 函数,如:

1
2
shared_ptr <T > a ( new T ( ) ) ;
a. reset ( ) ; // 此后 a 原先所指的对象会被销毁,并且 a 会变成 NULL

当然理论上也可以这样写:

1
2
shared_ptr <T > a ( new T ( ) ) ;
a = shared_ptr <T > ( ) ; // 相当于给 a 赋一个新构造的 shared_ptr, 也就是 NULL

5. shared_ptr 的类型转换

shared_ptr 有两种类型转换的函数,一个是 static_pointer_cast, 一个是 dynamic_pointer_cast. 其实用法真的和 C++ 提供的 static_cast 和 dynamic_cast 很像,再结合 3.3. 的代码和以下类似的代码,几乎没什么好讲的:

1
2
3
shared_ptr <A > ptra ;
shared_ptr <B > ptrb ( new B ( ) ) ;
ptra = dynamic_pointer_cast <A > (ptrb ) ;

6. 从 shared_ptr 的对象获得传统 C 指针

很简单,可以这样用:

1
2
shared_ptr <T > ptr ( new T ( ) ) ;
T *p = ptr. get ( ) ; // 获得传统 C 指针

7. shared_ptr 的常见的其它用法

比如,“我想让一个已经构造好的共享指针,丢弃掉原来所指的对象(或者让其引用计数减 1),然后指向一个新的 new 出来的对象,该怎么办?”参考如下代码:

1
2
shared_ptr <T > ptr ( new T ( ) ) ;
ptr. reset ( new T ( ) ) ; // 原来所指的对象会被销毁

8. shared_ptr 的错误用法

一定要注意,本节所述所有方法,都是错误的!

8.1. 在“中途”使用传统 C 指针构造共享指针

所谓在中途,指的就是不从 new 的返回值直接构造共享指针,比如从 this 指针构造自己的共享指针等。

8.2. 从一个对象的传统 C 指针,构造出两个或以上的共享指针

其实这种和 8.1. 也是类似的,或者说,这种情况是 8.1. 的一种具体情况,比如,下面的代码是错误的:

1
2
3
T *a = new T ( ) ;
shared_ptr <T > ptr1 (a ) ;
shared_ptr <T > ptr2 (a ) ;

这样的话,ptr1 和 ptr2 的引用计数是单独算的,它们任意一个对象在析构的时候,都会销毁 a 所指的对象,所以,这个对象会被“销毁两次”。

9. shared_ptr 的局限

有关运行效率的问题在这里就不讨论了。其它方面,shared_ptr 的构造要求比较高,如果对象在创建的时候没有使用共享指针存储的话,之后也不能用共享指针管理这个对象了。如果有引用循环 (reference cycle), 也就是对象 a 有指向对象 b 的共享指针,对象 b 也有指向对象 a 的共享指针,那么它们都不会被析构。当然的,shared_ptr 也没有办法和 Garbage Collecting 比较,毕竟如果运行库能够干预,还是有算法可以检查到引用循环的。(例如求强连通分量的算法。)

尤其,在类的成员函数的编写的时候,有时我们经常希望得到“自己”的共享指针,但是这往往是无法得到的。此时也不能够从 this 指针构造自己的共享指针(参见 8.1.),所以有时很憋闷。

10. 总结

实际上上面这么多注意事项,中心思想就是一个:让 shared_ptr 正确地记录对象被引用次数。如果能悟出一点 shared_ptr 的工作原理,基本上不会弄出太危险的事情来。

转载于:http://euyuil.com/2344/

 

boost::shared_ptr的特点:

和前面介绍的boost::scoped_ptr相比,boost::shared_ptr可以共享对象的所有权,因此其使用范围基本上没有什么限制(还是有一些需要遵循的使用规则,下文中介绍),自然也可以使用在stl的容器中。另外它还是线程安全的,这点在多线程程序中也非常重要。

boost::shared_ptr的使用规则:

boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:

  1. 避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
  2. shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
  3. 不要构造一个临时的shared_ptr作为函数的参数。
    如下列代码则可能导致内存泄漏:
    void test()
    {
        foo(boost::shared_ptr<implementation>(new    implementation()),g());
    }
    正确的用法
    为 :
    void test()
    {
        boost::shared_ptr<implementation> sp    (new implementation());
        foo(sp,g());
    }
    //当函数g()抛异常的时候就会泄露了,这个是boost文档上特地注明的标准bad Practices,Effective C++ Third Edition 条款17 有讲到

 

boost::shared_ptr智能指针分析 1. 简介   boost.smart_ptr 库中最有价值、最重要的组成部分,也是最有用的。   shared_ptr 与 scoped_ptr 一样包装了new 操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr 也可以安全地放到标准容器中,并弥补了a 阅读详情

相关推荐

【BOOST C++指针专题03】共享指针boost::shared_ptr

boost::shared_ptr是另一个智能指针,与 boost::scoped_ptr有很大不同,本文阐述这种区别。

gongdiwudu的专栏 6410

[C++] Boost智能指针——boost::shared_ptr(使用及原理分析)

简介 boost::shared_ptr是可以共享所有权的指针。如果有多个shared_ptr共同管理同一个对象时,只有这些shared_ptr全部与该对象脱离关系之后,被管理的对象才会被释放。通过下面这个例子先了解下shared_ptr的基本用法: 1 #include <iostream> 2 #include <string> 3 #inc...

weixin_34162629的博客 1276

boost---共享指针boost::shared_ptr

1、特点: (1)、boost::shared_ptr不独占一个对象,它可以和其他boost::shared_ptr类型的智能指针共享所有权; (2)、使用引用计数来管理,当引用对象的最后一个智能指针销毁后,对象才会被释放; (3)、boost::shared_ptr的构造函数的第二个参数是一个普通函数或者函数对象,该参数用来销毁所含的对象,默认是delete。 (4)、随着bo...

小米的修行之路 1276

boost shared_ptr基本用法介绍

一、介绍 share_ptr包装了new操作符在堆上分配的动态对象,但他实现的是计数型的智能指针,share_ptr早期的名字就是counter_ptr,可以自由拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0时)它才删除被包装的动态分配的对象。share_ptr也可以安全地放到标准容器中,是在STL容器中存储指针最标准的解法。 template<class T> class shared_ptr { public: typedef T element_type; //

weixin_41176628的博客 4264

纽扣电池供电系统优化:NBM5100A与STM32F745VG组合方案

在低功耗物联网设备设计中,能量管理是核心挑战之一。纽扣电池因其体积小、成本低被广泛采用,但瞬时大电流需求常导致电压骤降和寿命缩短。通过超级电容缓冲技术,可以实现能量的细水长流式存储与集中释放。NBM5100A电源管理IC与STM32F745VG微控制器的组合方案,采用双阶段能量管理架构,先以恒定小电流充电,再通过电容释放大电流。这种方案不仅能提升系统稳定性,还能延长电池寿命3-5倍,特别适合智能门锁、无线传感器等需要间歇性高功率输出的场景。

weixin_29194255的博客 257

【已解决】Claude应用地区限制问题:通过Slack注册与魔法节点切换实战指南

本文详细介绍了如何通过Slack注册和切换魔法节点解决Claude应用地区限制问题。从Slack账号注册、创建工作区技巧,到突破地区限制的关键步骤和成功后的配置使用,提供了全面的实战指南。特别强调了节点选择和网络环境对解决'App unavailable'错误的重要性,帮助用户顺利使用Claude AI助手。

weixin_29209801的博客 1761

智能指针tr1::shared_ptr、boost::shared_ptr使用

对于tr1::shared_ptr在安装vs同时会自带安装,但是版本较低的不存在。而boost作为tr1的实现品,包含 “Algorithms Broken Compiler Workarounds Concurrent Programming Containers Correctness and Testing Data Structures Domain Specific Fu

younghz 5063

AI Agent技能评测框架SkillsBench:从黑盒评估到白盒技能拆解

在人工智能领域,模型评估是衡量技术进展的核心环节。传统评测基准如GLUE、MMLU主要关注模型的通用认知能力,但实际工程应用中,AI Agent需要的是在复杂场景中协调多种能力的“职业技能”。SkillsBench创新性地将Agent能力进行原子化拆解,定义了理解规划、工具调用、推理决策、交互安全等技能维度,并通过领域专家构建的评测集确保生态效度。这一框架为Agent开发提供了精准的“度量衡”,使性能优化从经验驱动转向数据驱动,同时为不同模型和框架提供了公平比较的基础,推动了AI Agent生态从“野蛮生长

weixin_30530339的博客 389

几种智能指针的比较(std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::weak_ptr)

几种智能指针的比较(std::auto_ptr、boost::scope_ptr、boost::share_ptr、boost::weak_ptr)

pinhole的博客 691

Notion访问卡顿?一键优化DNS与Hosts提升加载速度

本文针对Notion访问卡顿问题,提供了两种核心优化方案:修改Hosts文件与配置DNS。详细解析了卡顿根源在于网络链路,并手把手指导用户在Windows、Mac、iOS及Android设备上实施优化,旨在通过替换为更优线路,显著提升Notion的页面加载与同步速度。

fff88的博客 1197

Android Display Graphics #1 整体框架介绍一

手机屏上显示的内容,2D或3D ,如果是 3D 的,不管是 App 还是游戏,或者简单的图片界面,底层都是通过 GPU、 通过 OpenGL(ES)绘制出来的。是Java层的一个类,提供了一系列API,使用这些API可以实现各种的产品经理要求的效果。显示的不同阶段对这块内存的叫法不同,在上层可以是Window、ANnativeWindow、Surface、SurfaceView、layer、buffer,这些本质上没啥区别,可以广泛意义上理解为用于显示内容的那块内存,只不过各个阶段的操作接口不同。

oDwyane03的博客 1387

C++智指针之——boost::intrusive_ptr,一种与shared_ptr、unique_ptr截然不同的智能指针

智能指针boost::shared_ptr/std::shared_ptr使用了和数据无关的引用计数,在使用shared_ptr之前,必须要搞清楚资源的所有权和资源的使用权这两个问题(详见《C++代码整洁之道》一书关于智能指针的讲解)。 shared_ptr带来两个问题: 引用计数要在shared_ptr对象间共享,所以它只能位于堆上。这使得每次都需要重新new一小块内存。这导致性能问题(当然,可以配合std::make_shared<>()和std::enable_shared_from_

哦,原来你也在这里。 1303

Anaconda安装教程傻瓜教程

网上好多教程找的我心好累,为了方便新手安装,我这边整理了大致详细的教程,参考了好几个大佬的教程,废话不多说,直接开始~ **前言:**有人纠结先安装python还是安装anaconda,这边的建议是装anaconda,就不需要单独装python了。 其次,有小伙伴的Anaconda的安装分两种情况: 情况一:电脑现在没有装python或者现在装的可以卸载掉(装Anaconda时先卸python); 情况二:电脑目前装了python,但想保留它;

zlc2351951436的博客 5万+

Boost库智能指针boost::shared_ptr详解和常用场景使用错误示例以及解决方法

是 Boost 库中实现的一个智能指针模板类,用于管理动态分配的对象生命周期,采用引用计数机制。多个shared_ptr实例可以共享同一个对象的所有权,引用计数自动管理,最后一个shared_ptr销毁时,自动释放对象,避免内存泄漏。其中T是管理的对象类型。函数名说明返回当前共享对象的引用计数reset()释放当前管理对象,指针置空get()返回裸指针,不影响引用计数解引用指针,返回对象引用访问对象成员unique()判断是否唯一拥有者是强大的共享所有权智能指针。支持拷贝,自动管理引用计数。

qq_36812406的博客 747

【VisualStdio】手把手教你做一个上位机(1)控件设计布局

网上有很多形形色色的制作上位机教程,有些写的挺好的,但是过于单调。

m0_73409202的博客 5435

2025年9月GESP(C++四级):排兵布阵

作为将军,你自然需要合理地排兵布阵。地图可以视为n行m列的网格,适合排兵的网格以 1 标注,不适合排兵的网格以 0 标注。现在你需要在地图上选择一个矩形区域排兵,这个矩形区域内不能包含不适合排兵的网格。请问可选择的矩形区域最多能包含多少网格?

王老师青少年编程 1380

Boost智能指针:scoped_ptr shared_ptr weak_ptr

Boost智能指针:scoped_ptr shared_ptr weak_ptr 一. scoped_ptr boost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放。下列代码演示了该指针的基本应用: #include  #include  #include  cla

chenglinhust的专栏 1355

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

关于boost::shared_ptr 智能指针小例子

boost::shared_ptr 智能指针 可以共享所有权的只能指针,看如下小例子 #include &lt;iostream&gt; #include "boost/shared_ptr.hpp" #include &lt;string&gt; using namespace std; //定义一个结构体,表示是否有人在家 struct SomeOneAtHome{ SomeO...

hjxu2016的博客 838

VB摄像头监控

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

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

浅析Boost智能指针:scoped_ptr shared_ptr weak_ptr

虽然通过弱引用指针可以有效的解除循环引用,但这种方式必须在程序员能预见会出现循环引用的情况下才能使用,也可以是说这个仅仅是一种编译期的解决方案,如果程序在运行过程中出现了循环引用,还是会造成内存泄漏的 一. scoped_ptr boost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放。下列代码演示

kxywn的专栏 689

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

std::auto_ptr boost::shared_ptr智能指针的应用

C++ 智能指针详解   一、简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见。 用智能指针便可以有效缓解这类问题,本文主要讲解参见的智能指针的用法。包括:std::auto_ptr、boost::scoped_p

ungoneless的博客 590

C++ Boost智能指针深度解析:从shared_ptr到intrusive_ptr的实战指南

在C++编程中,内存管理是核心挑战之一,手动管理资源易导致内存泄漏和悬垂指针。智能指针作为一种自动化资源管理技术,通过RAII(资源获取即初始化)原则,在对象生命周期结束时自动释放资源,从而提升代码的安全性与健壮性。其原理基于引用计数或独占所有权,确保资源在不再需要时被正确清理。这项技术的核心价值在于简化复杂系统的资源管理,降低开发者的心智负担,并减少因手动管理引发的错误。在实际应用中,智能指针广泛用于多模块共享数据、管理动态数组、构建对象关系图(如场景图、观察者模式)以及包装第三方资源(如文件句柄、网络连

weixin_29913663的博客 223

C++ Boost库:共享所有权的智能指针 shared_ptr

文章目录1. 简介2. shared_ptr示例代码3. shared_ptr使用陷阱 1. 简介 shared_ptr是可以共享所有权的指针。如果有多个shared_ptr共同管理同一个对象时,只有这些 shared_ptr全部与该对象分离之后,被管理的对象才会被释放,使用需要包含头文件: #include <boost/shared_ptr.hpp> 注:c++11标准中std::shared_ptr与 boost::shared_ptr功能相似。 shared_ptr使用引用计数,每一

超级大洋葱的博客 2738

c++智能指针:boost::scoped_ptr,boost::shared_ptr,boost::scoped_array

boost::scoped_ptr使用示例:#include <iostream> #include <string> #include <boost/smart_ptr.hpp> using namespace std; class TestBody { public: TestBody(int param = 0):m_num(param) { m_info =

renyican的博客 512

智能指针boost::shared_ptr

【1】boost::shared_ptr简介 boost::shared_ptr属于boost库,定义在namespace boost中,包含头文件#include便可以使用。 上篇boost::scoped_ptr中我们看到boost::scoped_ptr独享所有权,不允许赋值、拷贝。 而boost::shared_ptr是专门用于共享所有权的,由于要共享所有权,其在内部使用了引用计数机

享受开发技术,享受计算机科学 1195
上一篇: 从一道题谈C++中构造函数调用构造函数
下一篇: C++ 实现内部类访问外部类
codestinity
博客等级 码龄16年 29粉丝 7原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值