C++  shared_from_this 资料搜索

关于shared_from_this 查找的资料:

1. TcpConnection用到了enable_shared_from_this这个基类,这个基类提供了一个shared_from_this()公用方法可以让子类内部获取到shared_ptr的对象,用来用在类实现过程中需要传递自身指针的地方。有几个点需要注意一下:

  • 虽然enable_shared_from_this是基类,但它确实在shared_ptr里面初始化enable_shared_from_this的成员weak_ptr。因此不能在子类的构造方法里面调用shared_from_this(),因为这个时候weak_ptr还是空值。
  • 为什么在类的内部不直接使用this指针,因为我们程序中用shared_ptr来管理指针,如果我们在类的内部传递的过程中用原始指针,这样类内部的引用shared_ptr不会察觉到,因为有可能我们传进去的时候已经被shared_ptr释放掉了

2. shared_ptr     enable_shared_from_this

一种避免内存泄漏的方式是, always use a named smart pointer variable to hold the result of new

shared_ptr<T>  p(new T);

boost文档中首先讲了enable_shared_from_this的作用 : The header <boost/enable_shared_from_this.hpp> defines the class template enable_shared_from_this. It is used as a base class that allows a shared_ptr to the current object to be obtained from within a member function.

  • enable_shared_from_this<D> 作为D的基类, 这样D就继承了它的两个public函数:

    shared_ptr<D> shared_from_this() ;    const shared_ptr<D>  shared_from_this  const ();

  • D对象本身是不可以直接调用 shared_from_this()的, 在boost的代码设计中, D继承自 enable_shared_from_this<D> 的 private成员  weak_ptr<D> weak_this_  是从第三方函数调用D._internal_accept_owner(shared_ptr<D> const * Dptr,  D * pD)  来初始化, 而这个第三方函数是在 shared_ptr.hpp中实现的, 且由 shared_ptr<>的构造函数调用(很容易的把this传过去)
 1 #include <boost/shared_ptr.hpp>
 2 #include <boost/enable_shared_from_this.hpp>
 3 #include <iostream>
 4
 5 using namespace std;
 6 using namespace boost;
 7
 8 class WY : public enable_shared_from_this<WY>{
 9 public:
10     WY (int i):i_(i) { cout << "WY‘s constructor" << endl; }
11
12     int i (){return i_;}
13
14     shared_ptr<WY> get_shared_ptr (){
15         cout << "in get_shared_ptr ==> i = " << i_ << endl;
16         return shared_from_this();
17     }
18 private :
19     int i_;
20 };
21
22 int main ()
23 {
24     WY wy(6);  //这个wy对象实际上它的成员(继承自enable_shared_from_this<WY>) weak_ptr<WY>, 并有被初始化, 所以调用wy.shared_from_this()会抛错
25     shared_ptr<WY> ptr(new WY(5));  //这个ptr所持有的WY, 其weak_ptr<WY>, 是初始化过的
26     shared_ptr<WY> p = ptr->shared_from_this();
27     ptr->get_shared_ptr();
28     wy.get_shared_ptr();
29     p = wy.shared_from_this();
30 }

24 行的 wy中的 weak_ptr没有被初始化, 25行ptr是初始化过的

程序到28行的时候打印出   in get_shared_ptr  i = 6 之后异常退出, 即只要用 wy调用 shared_from_this 程序即异常退出

关于上面第二点中的源代码剖析是针对 1-46-1来说的, 当我翻看以前版的源码时, 发现并不是这样实现的, 并没_internal_accept_owner 这个函数, 所以我们只需记住的时boost为外提供的使用方式, 那就是要  shared_ptr<D>  pD的持用的 D, 其中的weak_this_才是初始化过的, 才可调用其 shared_from_this, 以这样的方式   pD->shared_from_this()

3. shared_from_this()在一个类中需要传递类对象本身shared_ptr的地方使用shared_from_this函数来获得指向自身的shared_ptr,它是enable_shared_from_this<T>的成员函数,返回shared_ptr<T>。
首先需要注意的是:这个函数仅在shared_ptr<T>的构造函数被调用之后才能使用。原因是enable_shared_from_this::weak_ptr并不在enable_shared_from_this<T>构造函数中设置,而是在shared_ptr<T>的构造函数中设置。

a) 如下代码是错误的:

1 class D:public boost::enable_shared_from_this<D>
2  {
3  public:
4      D()
5   {
6          boost::shared_ptr<D> p=shared_from_this();
7     }
8 };  

原因很简单,在D的构造函数中虽然可以保证enable_shared_from_this<D>的构造函数已经被调用,但正如前面所说,weak_ptr还没有设置。 
b) 如下代码也是错误的:

 1 class D:public boost::enable_shared_from_this<D>
 2  {
 3  public:
 4      void func()
 5      {
 6          boost::shared_ptr<D> p=shared_from_this();
 7      }
 8  };
 9  void main()
10  {
11      D d;
12      d.func();
13  }  

错误原因同上。 
c) 如下代码是正确的:

1 void main()
2  {
3      boost::shared_ptr<D> d(new D);
4      d->func();
5  }  

这里boost::shared_ptr<D> d(new D)实际上执行了3个动作:
1. 首先调用enable_shared_from_this<D>的构造函数;
2. 其次调用D的构造函数;
3. 最后调用shared_ptr<D>的构造函数。
是第3个动作设置了enable_shared_from_this<D>的weak_ptr,而不是第1个动作。这个地方是很违背c++常理和逻辑的,必须小心。

结论是:不要在构造函数中使用shared_from_this;其次,如果要使用shared_ptr,则应该在所有地方均使用,不能使用D d这种方式,也决不要传递裸指针。

时间: 2024-10-13 12:09:37

C++  shared_from_this 资料搜索的相关文章

WebSocket 资料搜索

http://jwebsocket.org/ http://zh.wikipedia.org/wiki/WebSocket http://www.infoq.com/cn/news/2013/07/ee7-websocket-support http://blog.csdn.net/whucyl/article/details/20153207 http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html http://redstar

PHP+mysql数据库开发类似百度的搜索功能:中英文分词+全文检索(MySQL全文检索+中文分词(SCWS))

PHP+mysql数据库开发类似百度的搜索功能:中英文分词+全文检索 中文分词: a)   robbe PHP中文分词扩展: http://www.boyunjian.com/v/softd/robbe.html i.  Robbe完整版本下载:Robbe完整版本(PHP测试程序, 开发帮助文档, WinNT下php各版本的dll文件)下载: http://code.google.com/p/robbe(“谷歌”无法使用) b) SCWS(简易中文分词) 基于HTTP/POST的分词 : htt

02 超级搜索术——资源搜索:全面、快速查找全网你想要的任何信息、情报

02 超级搜索术——资源搜索:全面.快速查找全网你想要的任何信息.情报 2018-07-30 目录 1. 超级搜索心法2. 资源搜索逻辑  场景1 庞杂资料搜索逻辑  场景2 专业文献资料的搜索逻辑  场景3 视频网站搜索3. 搜索技巧 1. 超级搜索心法 返回 超级搜索心法:遇到一切问题,首先想到的是搜索. 搜索资源时,要先百度,后淘宝,实在不行用知乎 这里的资源包括但不限于资料,视频,文献.软件,这里的百度不是单只百度,而是一切搜索引擎,包括不限于百度.搜狗微信.谷歌等等,淘宝代指一切购物网

Google Hack的一些整理

这里是一些关于Google Hack方面的整理 黑客专用信息和资料搜索地址为: http://www.google.com/custom?hl=xx-hacker 这里是google关键字的用法,要设置它为中文,则是 http://www.google.com/custom?hl=zh-CN 英文则是http://www.google.com/custom?hl=en 常用的google关键字: foo1 foo2 (也就是关联,比如搜索xx公司 xx美女) operator:foo filet

MultCloud – 支持数据互传的网盘管理

MultCloud https://www.multcloud.com/ 是一款在线服务,可以在一个地方管理众多网盘,支持国产百度盘, 最具有特色的地方是你可以直接在 MultCloud 里操作将 Dropbox 的文件传输到百度盘中. MultCloud 支持的国外网盘较多, Dropbox.Google Drive.Skydrive.Amazon S3.SugarSync. Box.Copy,CloudMe.Cubby.MyDriver.WEB.DE.Yandex. HiDrive 以及 W

Win7上从硬盘安装Debian

最近一直想将笔记本搞成Win7+Debian双系统,因为不管如何优化,2G内存的Win7笔记本上开个Linux虚拟机都实在吃力.经过一段时间的资料搜索,并阅读Debian官方的安装文档,今天终于实现.看网上很多文章的方法都感觉很麻烦,又要下载grub4dos,又要改boot.ini(Win7上没有boot.ini,取代的是bcdedit),又要改什么menu.lst.其实如果仅仅是想从Win7安装Debian,实现双系统并存,而没有其它要求的话,步骤并没有这么复杂.另外,网上很多文章(尤其中文文

数模讲座笔记

数模讲座笔记 概述 97%的参赛队是中国人 奖项分为O奖,F奖,M奖(一等奖),H奖(二等奖),S奖(成功参赛奖) 评审 初审:只有两个评委,审阅时间很快,10min左右 初审对所有的队伍进行打分,会刷掉近一半的队伍,刷掉的队伍一般获S奖 终审:分三轮 一二轮:决定前20名进入第三轮,剩下的按排名获M奖,H奖 三轮:直接决定O奖或F奖,评奖很主观,详见PPT 论文技巧 资料搜索时 搜索相关文献,大数据相关题目可用爬虫之类的工具 文献综述 了解问题的背景:连续题?离散题?大数据?网络流?环境相关?

Google基本利用

site:baidu.com #用于收集子域名  不要输入WWW intitle:管理登录 Filetype:php  #标题中带有管理登录并且还是PHP语言的 inurl:login.php #只要URL包含了login.php都会列出 intext #正文中存在关键字的页面 intitle #标题中存在的关键字网页 info #一些基本信息 inurl #URL存在关键字的网页 filetype #搜索指定文件类型 www.google.com/intl/xx-hacker 黑客专用入口 w

Unity视频播放可添加控制按钮方案

一般在游戏中,经常会有一段游戏故事背景视频,而且有一个跳过的按钮,点击后会跳过视频进入游戏.经过资料搜索,一般在Unity的话,在手机终端会调用 Handheld.PlayFullScreenMovie("test.mp4",Color.black, FullScreenMovieControlMode.CancelOnInput); 最后一个参数总共有4种: FullScreenMovieControlMode.CancelOnInput, FullScreenMovieContro