weak_ptr的构造函数

weak_ptr是用来解决shared_ptr的循环引用问题的。先看看如何构造weak_ptr:

int main(int argc, char** argv) {
    shared_ptr<int> p(new int(5));
    weak_ptr<int> q(p);
    
    weak_ptr<int> x;
    
    weak_ptr<int> y(new int(6));

最后一个创建语句编译报错,因为weak_ptr构造函数不能像普通智能指针一样接受裸指针。

看看构造函数的几种实现:

    weak_ptr(): px(0), pn() // never throws in 1.30+
    {
    }

这是默认构造函数,两个成员变量分别是:

    T * px;                       // contained pointer
    boost::detail::weak_count pn; // reference counter
px是裸指针,默认构造函数将之置为0

pn是引用计数器,这是一个对象。但是这个计数器对象用的却不是shared_ptr里面采用的类型。如果从shared_ptr获得的指针交给了weak_ptr, weak_ptr内部使用的是不同的引用计数器,也就是打破了引用循环。

  weak_count以后再分析,大概功能先了解到这里。

现在看一个重要函数lock

    shared_ptr<T> lock() const // never throws
    {
        return shared_ptr<element_type>( *this, boost::detail::sp_nothrow_tag() );
    }
weak_ptr的lock函数内部用自己构造了一个shared_ptr对象,然后返回之。看一下shared_ptr的构造函数,只要weak_ptr参数的引用计数不为空, 就将其中的指针赋给自己。
lock因为传递了sp_nothrow_tag给shared_ptr构造函数, 因此不会抛出异常。如果不想这样,也可以直接shared_ptr构造函数。

因此将weak_ptr变为shared_ptr有两种方法,

1.用lock

2.用shared_ptr构造函数


template<class Y>
    weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
    : px(r.lock().get()), pn(r.pn) // never throws
    {
    }
这个构造函数接受weak_ptr作为参数。lock参考下面的解释。

这里要注意,weak_ptr不提供get方法获取裸指针,只能通过lock().get()获取。也就是先转成shared_ptr,再获取裸指针。

    template<class Y>
    weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
    : px( r.px ), pn( r.pn ) // never throws
    {
    }

这个构造函数接受shared_ptr作为参数。






你可能感兴趣的:(weak_ptr的构造函数)