zoukankan      html  css  js  c++  java
  • 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 .
    ");
        }
    
        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
    }
  • 相关阅读:
    struts token令牌机制
    javascript的splice()方法备注
    [转的哦】 Android字符串资源及其格式化Android 中的string.xml用法小结
    3.Android I/O文件写入和读取
    Android开发_读取联系人信息_读取通讯录号码
    ListView的美化涉及到的一些属性
    4.Android添加背景音乐的方法
    Android 网络协议
    ContentValues 和HashTable之间的区别
    5.Andorid绘图方法(Canvas)
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/10294507.html
Copyright © 2011-2022 走看看