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 }