weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手,而不是智能指针,由于它不具备普通指针的行为,没有重载operator*和operator->,它的最大做用在于协助shared_ptr,像旁观者那样观测资源的使用状况。ios
但它有一个很大的缺点,那就是不能管理循环引用的对象。 函数
#include <boost/shared_ptr.hpp> #include <iostream> using namespace std; class Parent; class Child; typedef boost::shared_ptr<Parent> parent_ptr; typedef boost::shared_ptr<Child> child_ptr; class Child { public: Child() { cout << "Child ..." << endl; } ~Child() { cout << "~Child ..." << endl; } parent_ptr parent_; }; class Parent { public: Parent() { cout << "Parent ..." << endl; } ~Parent() { cout << "~Parent ..." << endl; } child_ptr child_; }; int main(void) { parent_ptr parent(new Parent); child_ptr child(new Child); parent->child_ = child; child->parent_ = parent; return 0; }
amespace boost { template<typename T> class weak_ptr { public: template <typename Y> weak_ptr(const shared_ptr<Y> &r); weak_ptr(const weak_ptr &r); template<class Y> weak_ptr &operator=( weak_ptr<Y> && r ); template<class Y> weak_ptr &operator=(shared_ptr<Y> const &r); ~weak_ptr(); bool expired() const; shared_ptr<T> lock() const; }; }
两个经常使用的功能函数:expired()用于检测所管理的对象是否已经释放;lock()用于获取所管理的对象的强引用智能指针。spa
强引用与弱引用:设计
强引用,只要有一个引用存在,对象就不能释放指针
弱引用,并不增长对象的引用计数(其实是不增长use_count_, 会增长weak_count_);但它能知道对象是否存在code
经过weak_ptr访问对象的成员的时候,要提高为shared_ptr对象
若是存在,提高为shared_ptr(强引用)成功
若是不存在,提高失败
对于上述的例子,只须要将Parent 类里面的成员定义改成以下,便可解决循环引用问题:blog
class Parent { public: boost::weak_ptr<parent> child_; };
由于此例子涉及到循环引用,并且是类成员引用着另外一个类,涉及到两种智能指针,跟踪起来难度很大,我也没什么心情像分析shared_ptr 同样画多个图来解释流程,这个例子须要解释的代码远远比shared_ptr 多,这里只是解释怎样使用。内存
下面再举个例子说明lock() 和 expired() 函数的用法:资源
#include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include <boost/scoped_array.hpp> #include <boost/scoped_ptr.hpp> #include <iostream> using namespace std; class X { public: X() { cout << "X ..." << endl; } ~X() { cout << "~X ..." << endl; } void Fun() { cout << "Fun ..." << endl; } }; int main(void) { boost::weak_ptr<X> p; boost::shared_ptr<X> p3; { boost::shared_ptr<X> p2(new X); cout << p2.use_count() << endl; p = p2; cout << p2.use_count() << endl; /*boost::shared_ptr<X> */ p3 = p.lock(); cout << p3.use_count() << endl; if (!p3) cout << "object is destroyed" << endl; else p3->Fun(); } /*boost::shared_ptr<X> p4 = p.lock(); if (!p4) cout<<"object is destroyed"<<endl; else p4->Fun();*/ if (p.expired()) cout << "object is destroyed" << endl; else cout << "object is alived" << endl; return 0; }
从输出能够看出,当p = p2; 时并未增长use_count_,因此p2.use_count() 仍是返回1,而从p 提高为 p3,增长了use_count_, p3.use_count() 返回2;出了大括号,p2 被析构,use_count_ 减为1,程序末尾结束,p3 被析构,use_count_ 减为0,X 就被析构了。
总结:
weak_ptr是一个“弱”指针,但它可以完成一些特殊的工做,足以证实它的存在价值。
weak_ptr被设计为与shared_ptr共同工做,能够从一个shared_ptr或者另外一个weak_ptr对象构造,得到资源的观测权。但weak_ptr没有共享资源,它的构造不会引发指针引用计数的增长。一样,在weak_ptr析构时也不会致使引用计数的减小,它只是一个静静地观察者。
使用weak_ptr的成员函数use_count()能够观测资源的引用计数,另外一个成员函数expired()的功能等价于use_count() == 0,但更快,表示观测的资源(也就是shared_ptr管理的资源)已经不复存在了。
weak_ptr 没有重载operator*和->,这是特地的,由于它不共享指针,不能操做资源,这是它弱的缘由。但它可使用一个很是重要的成员函数lock()从被观测的shared_ptr得到一个可用的shared_ptr对象,从而操做资源。当expired() == true的时候,lock()函数将返回一个存储空指针的shared_ptr。