boost::weak_ptr和enable_shared_from_this

boost::weak_ptr和enable_shared_from_this

 

shared_ptr在我的实践中使用很广,在接口层面上,我基本都会默认的使用shared_ptr.而weak_ptr则很少使用;即便使用,也是间接的使用,例如使得class A继承自boost::enable_shared_from_this,这样A便具有了一个weak_ptr的成员对象,我便可以通过接口shared_from_this()得到一个boost::shared_ptr<A>的对象.

除此之外,在实践中我几乎没有用到weak_ptr.到目前为止,我见到的对weak_ptr论述最好的是<<Beyond.the.C.plus.plus.Standard.Library.An.Introduction.to.Boost>>.本书给出了使用weak_ptr的三种场景: 打破递归的依赖关系;使用一个共享的资源而不需要共享所有权;避免悬空的指针.

后面两种场景相对比较容易明白,对于第一种则相对模糊.最近几天我相对仔细的研究了一下shared_ptr和weak_ptr的源代码,给出我自己的理解如下.

 

weak_ptr是依附于shared_ptr的,所以首先要把shared_ptr弄清楚;另外,我认为boost::enable_shared_from_this是解释递归的依赖关系的最好例子,所以使用这个实例解释weak_ptr最好不过了.

 

shared_ptr的图解

 

 

 

 

    如图所示,3个智能指针对象sp1,sp2,sp3,共享同一个对象object和同一个计数器counter,当3个指针对象sp1,sp2,sp3声明周期结束的时候,counter==0,object会被销毁(当然,这个销毁器本身可以由你定制).

shared_ptr的一个很大的特点是:counter==0,object会被销毁;反之,如果counter总是不为0,那么object会成为永久对象,例如全局对象.

 

在http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.html中给出了一个从this获得shared_ptr的实例,答案是使用weak_ptr,问题是为什么是weak_ptr.

 

让我们把这个问题重新说明一下:

struct X

{

         boost::shared_ptr<X>getX()

{

         boost::shared_ptr<X>r ;//????如何实现

         return r;

}

};

 

要得到X的智能指针,只是在对象指针是受shared_ptr保护的基础上的,举例如下:

void test_X()

{

         {

X x;

                  boost::shared_ptr<X> px =x.getX();//错误

}

         {

X* x = new X();

boost::shared_ptr<X> px = x->getX();//错误

}

         {

boost::shared_ptr<X>  x (new X());

boost::shared_ptr<X> px = x->getX();//正确

}

}

我们再回到原来的问题上,如何实现X::getX()函数.要构造X的智能指针,需要知道两个信息,object的指针和object的计数器,显然,指针本身可以通过this获得,问题是如何获得计数器,也即上面图中的counter.很显然,我们必须在X上存储某些信息来得到计数器.

最先想到的也许是使用一个指向counter的指针存储在X上面,这样应该是可以的,但是存在一个问题:暴露了shared_ptr的实现细节,虽然shared_ptr是基于计数器的,但是这不属于用户需要知道的事情.最好的方式是让shared_ptr本身来充当这个角色,这样所有的实现细节就都封装在shared_ptr内部了.

经过这样改装的shared_ptr的图解是:

 
 
 
 

     经过这样包装的object,问题立刻暴露出来:循环引用,造成object对象无法释放,成为”全局对象”.很显然,问题在于object本身参与了引用计数,也就是所有权的分享.我们需要的是不同于shared_ptr的这样的一类共享指针:他们并不参与对象的所有权,只是能够观察到对象的所有权.而这正是weak_ptr的本质所在.

当然了,weak_ptr还有其他的特征:查看对象指针是否过期(这也是比裸指针好的地方).

循环引用的情况很罕见,这可能也是我在实际中很少使用weak_ptr的原因吧.

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebSite和Web Application\网站与Web项目的区别

简要记录下&#xff1a;1、web应用程序Default.aspx显示有两个原有文件及Default.aspx.cs和Default.aspx.designer.cs&#xff1b;1、Web网站Default.aspx显示有一个原有文件Default.aspx.cs。 2、web应用程序有重新生成和发布两项&#xff1b;Web网站只有一个发布网站。 3、we…

linux(centos7)安装jdk

一、下载jdk1.8压缩包 官网链接如下&#xff1a; jdk官网 用xftp直接传输文件&#xff0c; 把下载好的jdk压缩包上传到Linux的文件夹下去到我们存放软件的文件夹下面&#xff0c;将刚刚下载好的压缩包通过如下命令进行解压&#xff1a; tar -zxvf jdk-8u321-linux-x64.tar.g…

inner join 和join的区别_left join、right join和join ???

点击上方“JAVA”&#xff0c;星标公众号重磅干货&#xff0c;第一时间送达有个困扰 说到SQL&#xff0c;很多人可能用了挺久&#xff0c;但依然有个问题一直困扰着&#xff0c;那就是 left join、 join、 right join和 inner join等等各种 join的区别。网上搜&#xff0c;最常…

黑马程序员顺义校区php_黑马程序员:从PHP零基础到月薪11K为何送锦旗给班主任?...

2016年我在传智播客学习完PHP以后&#xff0c;特意给班主任王智慧老师送了一面锦旗。为什么我会送锦旗&#xff0c;那是因为从她当我们班主任开始&#xff0c;就非常的负责&#xff0c;对我们非常的好&#xff0c;这个可以随便问问班里的同学。而且我能找到高薪工作跟她对我的鼓…

C++中std::tr1::function和bind 组件的使用

在C的TR1中(Technology Report)中包含一个function模板类和bind模板函数&#xff0c;使用它们可以实现类似函数指针的功能&#xff0c;但却却比函数指针更加灵活&#xff0c;特别是函数指向类的非静态成员函数时。可以参考Scott Meyers. <<Effective C (3rd Edition)>…

linux(centos7)安装MySQL

一、删除MariaDB的文件 通过命令查询MariaDB&#xff1a;rpm -pa | grep mariadb 通过命令删除查找到的程序rpm -e 查找到的文件名 如果删除失败&#xff0c;就通过下面的命令强制删除&#xff1a;rpm -e --nodeps 查找到的文件名 二、安装MySQL 1、安装mysql repo源 …

python ddos攻击脚本_python版本DDOS攻击脚本

今天为了休息下&#xff0c;换换脑子&#xff0c;于是就找到了我之前收藏的一篇python的文章&#xff0c;是关于ddos攻击的一个脚本&#xff0c;正好今天有空&#xff0c;就实践下了。 附上源码pyDdos.py:#!/usr/bin/env python import socket import time import threading #P…

设计模式 - Command

意图&#xff1a;将一个请求封装为一个对象&#xff0c;从而使你可用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志&#xff0c;以及支持可撤消的操作。 class Receiver { public:Receiver(){}virtual ~Receiver(){}virtual void Action(){cout<<&quo…

代码中特殊的注释技术——TODO、FIXME和XXX的用处

前言&#xff1a;今天在阅读Qt Creator的源代码时&#xff0c;发现一些注释中有FIXME英文单词&#xff0c;用英文词典居然查不到其意义&#xff01;实际上&#xff0c;在阅读一些开源代码时&#xff0c;我们常会碰到诸如&#xff1a;TODO、FIXME和XXX的单词&#xff0c;它们是…

我有机器人合体成一个大力神_史上最菜大力神(三)——SS加强级高塔

史上最菜大力神&#xff08;三&#xff09;——SS加强级高塔​mp.weixin.qq.com上次开箱废渣和狂暴的时候&#xff0c;误把电影中出现的高塔当作废渣&#xff0c;犯下了一个不大不小的错误&#xff0c;如今真正的高塔终于来了。史上最菜大力神&#xff08;一&#xff09;——SS…

c语言判断闰年_C语言1博客作业06 - D丶千思

1.作业头实验作业输入在一行中按照格式“yyyy/mm/dd”(即“年/月/日”)给出日期。注意&#xff1a;闰年的判别条件是该年年份能被4整除但不能被100整除、或者能被400整除。闰年的2月有29天。.1数据处理数据表达&#xff1a;采用整形定义变量Y(year)&#xff0c;M(month)&#x…

新版本idea的run/debug configuration

点击Edit Configuration点击modify options的下拉选项根据需要勾选相应的选项

登录用户Eclipse中SVN访问用户的变更办法

废话就不多说了&#xff0c;开始。。。 有点标题党了&#xff0c;呵呵 其实不止Eclipse成集SVN&#xff0c;全部SVN拜访用户的更变&#xff0c;都可以参照面下的式方 每日一道理 谁说人与人隔着遥远的重洋&#xff0c;谁说心与心设着坚固的堤防&#xff1f;十六岁的鸟儿飞上天空…

无法渲染窗口发黄_基础c4d教程:OC渲染器的立体光照

一、效果图昨天才把C4DR19安装好&#xff0c;之前安装一直在说无法找到系统的什么dll&#xff0c;后面查了好多方法终于弄好了&#xff0c;今天我也是第一次使用OC渲染&#xff0c;所以可能调节就没有那么好&#xff0c;大家一起进步吧&#xff01;二、教程1、首先打开我们的C4…

java8 list 去重_Java8-Stream在集合中的8种应用案例

前言Java8新特性我们使用的应该比较多了&#xff0c;今天这里整理了个人使用最多的8种场景&#xff0c;希望对大家有所帮助。Java Stream在集合中的运用案例遍历遍历也许是我们使用最多的功能了&#xff0c;在Java8之前我们遍历集合通常会采用for循环&#xff0c;迭代器&#x…

springboot——热部署

一、手动启动热部署 在进行 Spring Boot 的 Web 项目开发中&#xff0c;我们经常会遇到源代码文件、 配置文件等的修改&#xff0c;但每次修改后都会重启 Web 服务器才能修改后的文件生效&#xff0c; 这样很耗时&#xff0c;影响开发效率。而热部署就是不需要重启 Web 服务器就…

(转载)ubuntu开启SSH服务

&#xff08;转载&#xff09; http://www.cnblogs.com/xiazh/archive/2010/08/13/1798844.htmlSSH分客户端openssh-client和openssh-server如果你只是想登陆别的机器的SSH只需要安装openssh-client&#xff08;ubuntu有默认安装&#xff0c;如果没有则sudo apt-get install op…

cmake 学习笔记(一)

最大的Qt4程序群(KDE4)采用cmake作为构建系统Qt4的python绑定(pyside)采用了cmake作为构建系统开源的图像处理库 opencv 采用cmake 作为构建系统... 看来不学习一下cmake是不行了&#xff0c;一点一点来吧&#xff0c;找个最简单的C程序&#xff0c;慢慢复杂化&#xff0c;试试…

c++邮递员投递经过特定点_厉害了斑马鱼,动物实验体天团C位

明明是一条鱼&#xff0c;为什么在保健食品以及药品领域即将成为实验动物C位&#xff1f;越来越多的药品及保健食品企业&#xff0c;都想邀请它们成为座上宾&#xff0c;是时候展示真正的技术了&#xff01;透明就是很厉害斑马鱼从胚胎阶段至未来的成熟阶段&#xff0c;身体中有…

选了combobox里的选项后没激发change事件_备胎测试:来测测你被备胎了没?

很多人在感情里被备胎而不自知&#xff0c;今天就来教大家如何辨别备胎。你知道备胎的最大特征是什么吗&#xff1f;是在面对关系定位时&#xff0c;态度上的模棱两可。想想你身边养备胎的人&#xff0c;如果没有的话&#xff0c;想想电视剧或小说里养备胎的人&#xff0c;想想…