为何会有enable_share_from_this

这几天看到了这个东西,一直很疑惑这是干嘛的,看到stackoverflow上面的一个大牛的解释,原话如下:

The key point is that the “obvious” technique of just returning shared_ptr(this) is broken, because this winds up creating multiple distinct shared_ptr objects with separate reference counts. For this reason you must never create more than one shared_ptr from the same raw pointer

结合自己的理解,解说一下:
shared_ptr有两种构成方法,从原始指针转换过来,通过其他的shared_ptr生成.

后面一种我们知道,这也是shared_ptr存在的核心意义所在.前面一种我们也必须用过.
比如:

shared_ptr<X> p(new X());
此时,若我们
shared_ptr<X> q = p;

我们很自然地知道了,new X()生成的指针对象只会在p和q都死掉(生命周期结束)之后才会析构一次.

当如果是这样呢?

X* p = new X();
shared_ptr<X> a(p);
shared_ptr<X> b(p);

很显然,此时不出意外程序是会出错的,p指向的堆被重复析构了,在a和b死掉的时候delete p都会被调用.

同样的

class X {
shared_ptr<X> getX()
{
shared_ptr<X> r(this);
return r;
}
};

shared_ptr<X> p(new X());
X& a = *p;
shared_ptr<X> q = a.getX();

同理,此时new X()的指针对象将会被重复析构.
q的构成此时直接越过了p的管辖,从原始指针再次生成一个shared_ptr.
enable_share_from_this就可以解决上面的问题……

注意

D对象本身是不可以直接调用 shared_from_this()的, 在boost的代码设计中, D继承自 enable_shared_from_this 的 private成员 weak_ptr weak_this_ 是从第三方函数调用D._internal_accept_owner(shared_ptr const * Dptr, D * pD) 来初始化, 而这个第三方函数是在 shared_ptr.hpp中实现的, 且由 shared_ptr<>的构造函数调用(很容易的把this传过去)

 #include <boost/shared_ptr.hpp>
 #include <boost/enable_shared_from_this.hpp>
 #include <iostream>

 using namespace std;
 using namespace boost;

 class WY : public enable_shared_from_this<WY>{
 public:
    WY (int i):i_(i) { cout << "WY's constructor" << endl; }

     int i (){return i_;}

     shared_ptr<WY> get_shared_ptr (){
         cout << "in get_shared_ptr ==> i = " << i_ << endl;
         return shared_from_this();
     }
 private :
     int i_;
 };

 int main ()
 {
     WY wy(6);  //这个wy对象实际上它的成员(继承自enable_shared_from_this<WY>) weak_ptr<WY>, 并有被初始化, 所以调用wy.shared_from_this()会抛错
     shared_ptr<WY> ptr(new WY(5));  //这个ptr所持有的WY, 其weak_ptr<WY>, 是初始化过的
     shared_ptr<WY> p = ptr->shared_from_this();
     ptr->get_shared_ptr();
     wy.get_shared_ptr();
     p = wy.shared_from_this();
 }

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

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

参考

smart pointer — shared_from_this的使用

为何会有enable_share_from_this

你可能感兴趣的:(Enable,point)