,它的..."/>
您好,登錄后才能下訂單哦!
1、weak_ptr
(1)、weak_ptr是為了配合shared_ptr而引入的智能指針,它更像是shared_ptr的一個(gè)助手,它不具有普通指針的行為,
沒(méi)有重載operator*和->,它的最大作用在于協(xié)助shared_ptr工作,像旁觀者那樣觀測(cè)資源的使用情況。
(2)、2個(gè)重要接口:bool expired()const ;// 判斷是否過(guò)期
lock()函數(shù)是弱指針的核心;
(3)、獲得資源的觀測(cè)權(quán),但weak_ptr沒(méi)有共享資源,它的構(gòu)造不會(huì)引起引用計(jì)數(shù)的增加,它的析構(gòu)也不會(huì)導(dǎo)致引用計(jì)數(shù)減少,
它只是一個(gè)靜靜的觀察者。
2、使用weak_ptr
調(diào)用系統(tǒng)庫(kù)的:
#include<iostream> #include<boost/smart_ptr.hpp> using namespace std; using namespace boost; int main(void){ int *p = new int(10); shared_ptr<int> sp(p); weak_ptr<int> wp(sp);//1、本身對(duì)wp的創(chuàng)建與析構(gòu)是不會(huì)增加/減少use_count; cout<<wp.use_count()<<endl;//2、顯示的是它所觀測(cè)對(duì)象的引用計(jì)數(shù)器 if(!wp.expired()){ //沒(méi)過(guò)期(use_count != 0,空間還沒(méi)釋放) shared_ptr<int> sp1 = wp.lock(); //3、wp的lock()函數(shù)在有效的前提下可以構(gòu)造對(duì)象(構(gòu)造的是所觀測(cè)的對(duì)象)。 //使use_count加1; }//失效的話,構(gòu)建的是一個(gè)空對(duì)象,引用計(jì)數(shù)將不會(huì)在增加?。。? }
3、weak_ptr源碼剖析
結(jié)合shared_ptr和前面的所有,刪除器,shared_array、weak_ptr給出模擬的部分代碼:
模仿源代碼,寫出了最重要的函數(shù):
#ifndef _CONFIG_H_ #define _CONFIG_H_ #include<iostream> using namespace std; //#define DISPLAY #endif ////////////////////////////////////////////////////////////////////////////////////////// #ifndef _SHARED_PTR_H_ #define _SHARED_PTR_H_ #include"shared_count.h" template<class T> class weak_ptr; template<class T> class shared_ptr{ friend class weak_ptr<T>; typedef shared_ptr<T> this_type; public: template<class Y, class D> shared_ptr(Y *p, D d) : px(p), pn(p, d){}//支持傳遞刪除器 shared_ptr(T *p = 0) : px(p), pn(p){ #ifdef DISPLAY cout<<"Create shared_ptr object!"<<endl; #endif } shared_ptr(shared_ptr<T> const &r) : px(r.px), pn(r.pn){} shared_ptr<T>& operator=(shared_ptr<T> const &r){ if(this != &r){ this_type(r).swap(*this);//調(diào)用拷貝構(gòu)造,先創(chuàng)建一個(gè)無(wú)名臨時(shí)的對(duì)象 } return *this; } ~shared_ptr(){ #ifdef DISPLAY cout<<"Free shared_ptr object"<<endl; #endif } public: T& operator*()const{ return *(get()); } T* operator->()const{ return get(); } T* get()const{ return px; } public: long use_count()const{ return pn.use_count(); } bool unique()const{ return pn.unique(); } void reset(T *p){ this_type(p).swap(*this); } void swap(shared_ptr<T> &other){ std::swap(px, other.px); //指針的交換 pn.swap(other.pn); } public: template<class Y> shared_ptr(weak_ptr<Y> const &r) : pn(r.pn){ px = r.px; } private: T *px; shared_count pn; }; #endif ///////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _SHARED_COUNT_H_ #define _SHARED_COUNT_H_ #include"config.h" #include"sp_counted_base.h" #include"sp_counted_impl_xx.h" class shared_count{ friend class weak_count; public: template<class T> //此時(shí)類型不定,寫模板函數(shù) shared_count(T *p) : pi(new sp_counted_impl_xx<T>(p)){ #ifdef DISPLAY cout<<"Create shared_cout object!"<<endl; #endif } template<class Y, class D> shared_count(Y *p, D d) : pi(0){ typedef Y* P; pi = new sp_counted_impl_pd<P, D>(p, d); } shared_count(shared_count const &r) : pi(r.pi){ if(pi){ pi->add_ref_copy(); } } ~shared_count(){ #ifdef DISPLAY cout<<"Free shared_count object"<<endl; #endif if(pi){ pi->release(); } } public: long use_count()const{ return pi != 0 ? pi->use_count() : 0; } bool unique()const{ return use_count() == 1; } void swap(shared_count &r){ sp_counted_base *tmp = r.pi; r.pi = pi; pi = tmp; } public: explicit shared_count(weak_count const &r); private: sp_counted_base *pi; }; ///////////////////////////////////////////////////// template<class P, class D> class sp_counted_impl_pd : public sp_counted_base{ public: sp_counted_impl_pd(P p, D d) : ptr(p), del(d){} public: void dispose(){ del(ptr); } private: P ptr; D del; }; ///////////////////////////////////////////////////////////////////// class weak_count{ friend class shared_count; public: weak_count(shared_count const &r) : pi(r.pi){ if(pi != 0){ pi->weak_add_ref(); } } ~weak_count(){ if(pi){ pi->weak_release(); } } public: long use_count()const{ return pi != 0 ? pi->use_count() : 0; } private: sp_counted_base *pi; }; shared_count::shared_count(weak_count const &r) : pi(r.pi){ if(pi){ pi->add_ref_lock(); } } #endif ////////////////////////////////////////////////////////////////////////////// #ifndef SP_COUNTED_BASE_H_ #define SP_COUNTED_BASE_H_ #include"config.h" class sp_counted_base{ //抽象類 public: sp_counted_base() : use_count_(1), weak_count_(1){ #ifdef DISPLAY cout<<"Create sp_counted_base object"<<endl; #endif } virtual ~sp_counted_base(){ #ifdef DISPLAY cout<<"Free sp_counted_base object"<<endl; #endif } public: virtual void dispose() = 0; //純虛函數(shù) void release(){ if(--use_count_ == 0){ dispose(); delete this; } } public: long use_count()const{ return use_count_; } void add_ref_copy(){ ++use_count_; } void weak_add_ref(){ ++weak_count_; } virtual void destroy(){ delete this; } void weak_release(){ if(--weak_count_ == 0){ destroy(); } } bool add_ref_lock(){ if(use_count == 0){ return false; } ++use_count_; return true; } private: long use_count_; long weak_count_; }; #endif ///////////////////////////////////////////////////////////////////////////////// #ifndef _SHARED_ARRAY_H_ #define _SHARED_ARRAY_H_ #include"checked_delete.h" template<class T> class shared_array{ public: typedef checked_array_deleter<T> deleter; shared_array(T *p = 0) : px(p), pn(p, deleter()){} //無(wú)名對(duì)象 ~shared_array(){ } public: T& operator[](int i)const{ return px[i]; } private: T *px; shared_count pn; //必須用到引用計(jì)數(shù)器對(duì)象 }; #endif //////////////////////////////////////////////////////////////////////////////////////////// #ifndef _CHECKED_DELETE_H_ #define _CHECKED_DELETE_H_ template<class T> void checked_array_delete(T *x){ delete []x; } template<class T> struct checked_array_deleter{ public: void operator()(T *x)const{ checked_array_delete(x); } }; #endif ////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _WEAK_PTR_H_ #define _WEAK_PTR_H_ #include"shared_ptr.h" template<class T> class shared_ptr; class shared_count; template<class T> class weak_ptr{ friend class shared_ptr<T>; friend class shared_count; public: template<class Y> weak_ptr(shared_ptr<Y> const &r) : px(r.px), pn(r.pn){} ~weak_ptr(){} public: long use_count()const{ pn.use_count(); } bool expired()const{ return pn.use_count() == 0; } shared_ptr<T> lock()const{ return shared_ptr<T>(*this); } private: T *px; weak_count pn; }; #endif /////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef SP_COUNTED_IMPL_XX_H_ #define SP_COUNTED_IMPL_XX_H_ #include"sp_counted_base.h" template<class T> class sp_counted_impl_xx : public sp_counted_base{ public: sp_counted_impl_xx(T *p) : px_(p){ #ifdef DISPLAY cout<<"Create sp_counted_impl_xx object"<<endl; #endif } ~sp_counted_impl_xx(){ #ifdef DISPLAY cout<<"Free sp_counted_impl_xx object"<<endl; #endif } public: void dispose(){ delete px_; } private: T *px_; }; #endif /////////////////////////////////////////////////////////////////////////////////////////////////////// #include<iostream> #include"shared_ptr.h" #include"shared_array.h" #include"weak_ptr.h" using namespace std; int main(void){ int *p = new int(10); shared_ptr<int> sp(p); weak_ptr<int> wp(sp); if(!wp.expired()){ shared_ptr<int> sp1 = wp.lock();//返回真實(shí)的對(duì)象 cout<<sp.use_count()<<endl; } cout<<sp.use_count()<<endl; }
這是這個(gè)智能指針的最主要的剖析,關(guān)鍵理清脈絡(luò),條理清晰一些,就可以分析出來(lái)!
4、intrusive_ptr的使用
適用情景:(1)、對(duì)內(nèi)存的占用要求非常嚴(yán)格,不能有引用計(jì)數(shù)的內(nèi)存開(kāi)銷;
(2)、這時(shí)的代碼中已經(jīng)有了引用計(jì)數(shù)機(jī)制管理的對(duì)象;
重點(diǎn)掌握如何使用:
(1)、兩個(gè)方法必須重寫(增加/減少引用計(jì)數(shù))
(2)、必須自己編寫管理引用計(jì)數(shù)的類
(3)、要封裝到一個(gè)類中,在繼承(把自己的類侵入到智能指針中進(jìn)行管理)
具體使用的一個(gè)類子如下:
#include<iostream> #include<boost/smart_ptr.hpp> using namespace std; using namespace boost; //1、實(shí)現(xiàn)2個(gè)重要的函數(shù) template<class T> void intrusive_ptr_add_ref(T *t){ //增加引用計(jì)數(shù) t->add_ref_copy(); } template<class T> void intrusive_ptr_release(T *t){ //減少引用計(jì)數(shù) t->release(); } //2、提供管理對(duì)象 class Counter{ public: Counter() : use_count_(0){ } ~Counter(){ } public: void add_ref_copy(){ ++use_count_; } void release(){ if(--use_count_ == 0){ delete this; } } private: long use_count_; }; //3、定義自己的對(duì)象 class Test; ostream& operator<<(ostream &out, const Test &t); class Test : public Counter{ friend ostream& operator<<(ostream &out, const Test &t); public: Test(int d = 0) : data(d){} ~Test(){} private: int data; }; ostream& operator<<(ostream &out, const Test &t){ out<<t.data; return out; } int main(void){ Test *pt = new Test(10); intrusive_ptr<Test> ip(pt); cout<<*ip<<endl; }
結(jié)果如下:
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。