C++ 智能指针五

/*
代码分析:

这是标准库的源码,我们看到在enable_shared_from_this内部保存了一个weak_ptr。shared_from_this函数就是通过这个weak_ptr得到了。
但是另外一点,我们可以看到在enable_shared_from_this的构造函数中并没有对这个weak_ptr进行初始化。
这就是为什么我们不能在构造函数调用shared_from_this()的原因,因为其内部的weak_ptr并没有初始化。所以会产生错误。

在实际的编程中如果我们需要在对象初始化中用到自己的shared_ptr。可
以单独将初始化操作放到一个独立的init函数中,这时候再调用shared_from_this()是没有问题的(但还是有点问题,下面会讲到)

熟悉weak_ptr的同学可能知道,我们在使用weak_ptr前,需要用一个shared_ptr来对其进行初始化。
对weak_ptr初始化是要能获取到当前对象的引用计数对象,而引用计数对象可以通过shared_ptr对象获取到。
当然我们同样可以用一个已经初始化过的weak_ptr来初始化另一个weak_ptr,因为已初始化的weak_ptr也可能获取到对象的引用计数。

enable_shared_from_this内部的weak_ptr是通过_Do_enable函数初始化的。
而_Do_enable函数实在shared_ptr的构造函数中调用的,这是至关重要的一个环节。
正因为如此我们在调用shared_from_this之前请确保程序已经显式地创建了shared_ptr对象,
要不然enable_shared_from_this内部的weak_ptr始终是无效。

同理在析构函数中也不能调用shared_from_this()。  
在析构时,引用计数已经变为零,weak_ptr已经相当于指向的是一个无效的对象,这是不能通过此无效的weak_ptr构造shared_ptr。

*/

template<class _Ty> 
class enable_shared_from_this
{    
    // provide member functions that create shared_ptr to this
public:
    typedef _Ty _EStype;

    shared_ptr<_Ty> shared_from_this()
    {    // return shared_ptr
        return (shared_ptr<_Ty>(_Wptr));
    }

    shared_ptr<const _Ty> shared_from_this() const
    {    // return shared_ptr
        return (shared_ptr<const _Ty>(_Wptr));
    }

protected:
    enable_shared_from_this()
    {    // construct (do nothing)
    }

    enable_shared_from_this(const enable_shared_from_this&)
    {    // construct (do nothing)
    }

    enable_shared_from_this& operator=(const enable_shared_from_this&)
    {    // assign (do nothing)
        return (*this);
    }

    ~enable_shared_from_this()
    {    // destroy (do nothing)
    }

private:
    //友元函数
    template<class _Ty1,class _Ty2>
    friend void _Do_enable(_Ty1 *, enable_shared_from_this<_Ty2>*, _Ref_count_base *);

    mutable weak_ptr<_Ty> _Wptr;
};

template<class _Ty1,class _Ty2>
inline void _Do_enable(_Ty1 *_Ptr, enable_shared_from_this<_Ty2> *_Es, _Ref_count_base *_Refptr)
{    // reset internal weak pointer
    _Es->_Wptr._Resetw(_Ptr, _Refptr);
}
/* 智能指针shared_from_this崩溃问题分析 */

#include <iostream>
#include <memory>

class TestClass : public std::enable_shared_from_this<TestClass>
{
public:
    TestClass()
    {
    }
    ~TestClass()
    {
    }

    void show()
    {
        printf("hello world .\n");
    }

    std::shared_ptr<TestClass> getPtr()
    {
        return shared_from_this();
    }
};

int main()
{
    TestClass t;
    t.getPtr(); //shared_from_this()错误

    TestClass* t1(new TestClass());
    t1->getPtr();//shared_from_this()错误

    std::shared_ptr<TestClass> t2(new TestClass());
    t2->getPtr(); //正确,已提前创建了shared_ptr
}

 

posted on 2019-01-20 12:35  寒魔影  阅读(352)  评论(0编辑  收藏  举报

导航