您好,登錄后才能下訂單哦!
1、shared_ptr中的px出現原因
方便對其數據空間的管理,取值和獲取地址將極大的方便我們的操作。
2、解決析構函數
避免內存空間的泄漏。new出來的空間都沒有釋放掉!
釋放擁有權靠的是引用計數。
~shared_count(){ if(pi){ //判斷所指父類是否為空 pi->release(); //釋放new出來的對象和外部new出來的空間 } } //////////////////////////////////////////////////////////////////////// public: virtual void dispose() = 0; //純虛函數 void release(){ //在sp_counted_base中 if(--use_count_ == 0){ //判斷use_count是否為0 dispose(); //因為虛函數,所以子類中實現 delete this; //先調用析構函數,在釋放this指向的空間 } } /////////////////////////////////////////////////////////////////////// public: void dispose(){ delete px_; //釋放外部new出來的空間 }
因為要級聯釋放空間,所以sp_counted_base的析構函數必須是虛函數,才能先調用子類的析構,最后調用自己的析構函數。
結果如下:
use_count和unique函數的實現比較簡單
3、拷貝構造和賦值語句
此時應當相當于淺拷貝,use_count加1即可!模型如下:
此時應在shared_ptr和shared_count進行淺拷貝,并在shared_count中加入方法,
shared_count(shared_count const &r) : pi(r.pi){ if(pi){ pi->add_ref_copy(); //在父類中實現這個方法,只要讓++use_count_即可! } }
賦值語句,關鍵調用swap函數,的認真思考,畫畫圖就好理解多了(前面已經寫過這個了)。
這個賦值語句寫的真的很好,既讓use_count_加1,又可以讓原先的空間符合情況的釋放。
shared_ptr<T>& operator=(shared_ptr<T> const &r){ if(this != &r){ this_type(r).swap(*this);//調用拷貝構造,先創建一個無名臨時的對象, } //因為調用了拷貝構造,所以在shared_count中調用方法, return *this; //會讓use_count_加1的。 } ////////////////////////////////////////////////////////////////////////////////////// void swap(shared_ptr<T> &other){ std::swap(px, other.px); //指針的交換 pn.swap(other.pn); }
3、shared_ptr的模擬部分:
#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 shared_ptr{ typedef shared_ptr<T> this_type; public: 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);//調用拷貝構造,先創建一個無名臨時的對象 } 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); } 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{ public: template<class T> //此時類型不定,寫模板函數 shared_count(T *p) : pi(new sp_counted_impl_xx<T>(p)){ #ifdef DISPLAY cout<<"Create shared_cout object!"<<endl; #endif } 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; } private: sp_counted_base *pi; }; #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){ #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; //純虛函數 void release(){ if(--use_count_ == 0){ dispose(); delete this; } } public: long use_count()const{ return use_count_; } void add_ref_copy(){ ++use_count_; } private: long use_count_; }; #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" using namespace std; int main(void){ int *p = new int(10); shared_ptr<int> ps(p); cout<<ps.use_count()<<endl; cout<<ps.unique()<<endl; shared_ptr<int> ps1 = ps; cout<<ps.use_count()<<endl; cout<<ps.unique()<<endl; shared_ptr<int> ps2; ps2 = ps; cout<<ps.use_count()<<endl; cout<<ps.unique()<<endl; //cout<<*ps<<endl; }
以上就是對shared_ptr的部分源碼剖析的理解了。
4、刪除器
刪除器d可以是一個函數對象(是一個對象,但是使用起來像函數),也可以是一個函數指針;
可以根據自己定義的方式去管理(釋放)內存空間。
有2個特性:函數對象 operator()進行了重載
刪除器的使用,調用系統的:
#include<iostream> #include<boost/smart_ptr.hpp> using namespace std; using namespace boost; void My_Deleter(int *p){ //刪除器 cout<<"HaHa:"<<endl; delete p; } //靠刪除器來管理空間,而不再向之前的調用析構函數。 int main(void){ int *p = new int(10); //假設p是特殊的資源 shared_ptr<int> ps(p, My_Deleter); }
回過頭來,對自己的空間進行釋放,定義自定義的刪除器。不采用默認方式釋放,而是
采用自己的方式釋放!
刪除器自己模擬部分代碼:
public: template<class Y, class D> shared_ptr(Y *p, D d) : px(p), pn(p, d){}//支持傳遞刪除器 ///////////////////////////////////////////////////////////////////////////// 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); } /////////////////////////////////////////////////////////////////////////// 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(){ delete ptr; } private: P ptr; D del; }; ////////////////////////////////////////////////////////////////////////// #include<iostream> #include"shared_ptr.h" using namespace std; void My_Deleter(int *p){ //刪除器 cout<<"HaHa:"<<endl; delete p; } int main(void){ int *p = new int(10); shared_ptr<int> ps(p, My_Deleter); }
以上就是刪除器實現的主要代碼,是在shared_ptr中實現的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。