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。