zoukankan      html  css  js  c++  java
  • 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这种方式,也决不要传递裸指针。

  • 相关阅读:
    团队作业6——展示博客(alpha阶段)
    第八天敏捷冲刺
    第七天敏捷冲刺
    第六天敏捷冲刺
    第五天敏捷冲刺
    第四天敏捷冲刺
    第三天敏捷冲刺
    linux查询内存使用情况
    input hidden 属性
    于Java网络爬虫---模拟txt文件上传操作。
  • 原文地址:https://www.cnblogs.com/jianhui-Ethan/p/4680417.html
Copyright © 2011-2022 走看看