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(): px(0), pn() // never throws in 1.30+ { }
T * px; // contained pointer boost::detail::weak_count pn; // reference counterpx是裸指针,默认构造函数将之置为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参数的引用计数不为空, 就将其中的指针赋给自己。
因此将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作为参数。