zoukankan      html  css  js  c++  java
  • Boost源代码学习---weak_ptr.hpp

    weak_ptr是辅助shared_ptr的智能指针。

    就像它的名字一样。是个“弱”指针;仅有几个接口。仅能完毕非常少工作。它能够从一个shared_ptr或weak_ptr对象构造。获取对资源的观測权。它是没有共享资源的,所以它的对象的创建不会引起指针引用计数的添加,它的对象的析构也不会引起计数器的降低。

    它没有重载*和->。不能使用指针。基本的几个接口例如以下:

    long use_count() const//返回计数器数值
    bool expired() const//推断指针是否失效,也就是推断计数器是否为零
    shared_ptr<T> lock() const//返回一个shared_ptr<T>指针
    void reset()//重置weak_ptr
    void swap(weak_ptr<T> &b)//交换两个若指针

    weak_ptr的一个重要用途是获得this指针的shared_ptr,使对象可以生产shared_ptr管理自己:对象使用weak_ptr观測this指针(不影响计数器)。在须要使用shared_ptr的时候调用lock()函数。

    有一个类enable_shared_from_this<T>来帮助实现上述做法,它的头文件在<boost/enable_shared_from_this.hpp>中。主要声明:

    template<class T>
    class enable_shared_from_this
    {
    public:
    	shared_ptr<T> shared_from_this();
    };
    在使用的时候继承它既可使用shared_from_this来获取shared_ptr对象。(要注意不能使用非shared_ptr对象类使用这个函数,这样会导致shared_from_this返回的对象在析构时使用delete来释放栈上内存)。

    #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
    #define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
    
    //
    //  weak_ptr.hpp
    //
    //  Copyright (c) 2001, 2002, 2003 Peter Dimov
    //
    // Distributed under the Boost Software License, Version 1.0. (See
    // accompanying file LICENSE_1_0.txt or copy at
    // http://www.boost.org/LICENSE_1_0.txt)
    //
    //  See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
    //
    
    #include <memory> // boost.TR1 include order fix
    #include <boost/smart_ptr/detail/shared_count.hpp>
    #include <boost/smart_ptr/shared_ptr.hpp>
    
    namespace boost
    {
    
    template<class T> class weak_ptr
    {
    private:
    
        // Borland 5.5.1 specific workarounds
        typedef weak_ptr<T> this_type;
    
    public:
    
        typedef typename boost::detail::sp_element< T >::type element_type;
    		
    		//默认构造函数
        weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
        {
        }
    
    //  generated copy constructor, assignment, destructor are fine...
    
    #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
    
    // ... except in C++0x, move disables the implicit copy
    		//复制构造函数
        weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
        {
        }
    		//赋值操作符
        weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
        {
            px = r.px;
            pn = r.pn;
            return *this;
        }
    
    #endif
    
    //
    //  The "obvious" converting constructor implementation:
    //
    //  template<class Y>
    //  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
    //  {
    //  }
    //
    //  has a serious problem.
    //
    //  r.px may already have been invalidated. The px(r.px)
    //  conversion may require access to *r.px (virtual inheritance).
    //
    //  It is not possible to avoid spurious access violations since
    //  in multithreaded programs r.px may be invalidated at any point.
    //
    
        template<class Y>
    #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
    
        weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
    
    #else
    
        weak_ptr( weak_ptr<Y> const & r )
    
    #endif
        BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
        {
            boost::detail::sp_assert_convertible< Y, T >();
        }
    
    #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
    
        template<class Y>
    #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
    
        weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
    
    #else
    
        weak_ptr( weak_ptr<Y> && r )
    
    #endif
        BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
        {
            boost::detail::sp_assert_convertible< Y, T >();
            r.px = 0;
        }
    
        // for better efficiency in the T == Y case
        weak_ptr( weak_ptr && r )
        BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
        {
            r.px = 0;
        }
    
        // for better efficiency in the T == Y case
        weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
        {
            this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
            return *this;
        }
    
    
    #endif
    
        template<class Y>
    #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
    
        weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
    
    #else
    		//由shared_ptr创建weak_ptr
        weak_ptr( shared_ptr<Y> const & r )
    
    #endif
        BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
        {
            boost::detail::sp_assert_convertible< Y, T >();
        }
    
    #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
    
        template<class Y>
        weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
        {
            boost::detail::sp_assert_convertible< Y, T >();
    
            px = r.lock().get();
            pn = r.pn;
    
            return *this;
        }
    
    #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
    
        template<class Y>
        weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
        {
            this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
            return *this;
        }
    
    #endif
    
    		//赋值操作符,右值为shared_ptr
        template<class Y>
        weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
        {
            boost::detail::sp_assert_convertible< Y, T >();
    
            px = r.px;
            pn = r.pn;
    
            return *this;
        }
    
    #endif
    
    //基本的几个接口例如以下::
    
    		//返回shared_ptr对象
        shared_ptr<T> lock() const BOOST_NOEXCEPT
        {
            return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
        }
    		//返回计数器数值
        long use_count() const BOOST_NOEXCEPT
        {
            return pn.use_count();
        }
    		//推断指针是否有效。推断其计数器是否为零
        bool expired() const BOOST_NOEXCEPT
        {
            return pn.use_count() == 0;
        }
    
        bool _empty() const // extension, not in std::weak_ptr
        {
            return pn.empty();
        }
    
        void reset() BOOST_NOEXCEPT // never throws in 1.30+
        {
            this_type().swap(*this);
        }
    
        void swap(this_type & other) BOOST_NOEXCEPT
        {
            std::swap(px, other.px);
            pn.swap(other.pn);
        }
    
        template<typename Y>
        void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
        {
            px = px2;
            pn = r.pn;
        }
    
        template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
        {
            return pn < rhs.pn;
        }
    
        template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
        {
            return pn < rhs.pn;
        }
    
    // Tasteless as this may seem, making all members public allows member templates
    // to work in the absence of member template friends. (Matthew Langston)
    
    #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
    
    private:
    		//设为友元
        template<class Y> friend class weak_ptr;
        template<class Y> friend class shared_ptr;
    
    #endif
    		//类的成员变量
        element_type * px;            // contained pointer
        boost::detail::weak_count pn; // reference counter
    
    };  // weak_ptr
    
    template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
    {
        return a.owner_before( b );
    }
    
    template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
    {
        a.swap(b);
    }
    
    } // namespace boost
    
    #endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
    


  • 相关阅读:
    分层图最短路(DP思想) BZOJ2662 [BeiJing wc2012]冻结
    动态规划 BZOJ1925 地精部落
    线性DP SPOJ Mobile Service
    线性DP codevs2185 最长公共上升子序列
    数位DP POJ3208 Apocalypse Someday
    线性DP POJ3666 Making the Grade
    杨氏矩阵 线性DP? POJ2279 Mr.Young's Picture Permutations
    tarjan强连通分量 洛谷P1262 间谍网络
    树链剖分 BZOJ3589 动态树
    二分图 BZOJ4554 [Tjoi2016&Heoi2016]游戏
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7193721.html
Copyright © 2011-2022 走看看