C++ 比較煩惱的是內存的管理,new是簡單,不夠,delete偶爾就會忘記。或者說,出現,多個對象共享多一個內存,一個delete以后,導致其他也不能用的不良情況,所以就跑出了一個智能指針來進行管理。
?
設計需求:
1.該智能指針能接受各種類型的指針 -- 使用模板
2.智能指針需要知道該對象有多少個人在用他 -- 大家用的同一個計數器 int * num;
3.共同使用同一個內存 -- ?數據指針 T * data;
ps:目前為線程不安全的實現,若要達到線程安全,需要使用一個共同的互斥變量。
?
#ifndef SHARE_PTR_H #define SHARE_PTR_Htemplate<typename T> class share_ptr{ private:T * data;int * num; public:/*** @brief 構造函數,通過傳入的對象指針進行初始化,* 并將計數器置1*/share_ptr(T * t):data(t);/*** @brief 析構函數,判斷當前對象是否為最后一個,* 是就delete,不是就計數減1*/~share_ptr();/*** @brief 拷貝構造函數,通過rhs的值賦值,* 并將計數器加1*/share_ptr(share_ptr<T>& rhs);/*** @brief 賦值,判斷當前對象是否一致,* 是則返回,不是則析構之前的,并用現在的賦值,* 計數器加1*/share_ptr<T>& operator =( share_ptr<T>& rhs);/*** @brief 返回數據的引用*/T& operator *(){ return *data; } /*** @brief 返回數據的指針*/T* operator ->() { return data; } /*** @brief 獲取當前有多少個共同使用者*/int count(){ return *num;} };#endif //SHARE_PTR_H
?
實現
#ifndef SHARE_PTR_H #define SHARE_PTR_H#include <stdio.h> #include <iostream>#ifdef _DEBUG #define DEBUG(fmt) printf (fmt) #else #define DEBUG(x) #endiftemplate<typename T> class share_ptr{ private:T * data;int * num; public:share_ptr(T * t):data(t){num = new int;*num = 1;DEBUG("share_ptr(T * t):data(t)\n");}~share_ptr(){if(*num>1){(*num)--;DEBUG("~share_ptr,num = k\n");}else{DEBUG("~share_ptr,num = 0\n");delete data;delete num;data = NULL;num = NULL;}}//拷貝構造share_ptr(share_ptr<T>& rhs){data = rhs.data;num = rhs.num;(*num)++;DEBUG("share_ptr(share_ptr<T>& rhs)\n");}//賦值share_ptr<T>& operator =( share_ptr<T>& rhs){if( data == rhs.data){DEBUG("share_prt<T>& operator=(share_ptr<T>& rhs)\n");return *this;}else{//判斷本來指向的指針是否是最后一個,是的話,就delete掉,不是的話就*num--if(*num == 1){delete data;delete num;data = NULL;num = NULL;}else{ (*num)--; }data = rhs.data;num = rhs.num;(*num)++;}DEBUG("share_prt<T>& operator=(share_ptr<T>& rhs)\n");return *this;}T& operator *(){ return *data; } T* operator ->() { return data; } int count(){ return *num;} };#endif //SHARE_PTR_H
?
測試:
#include <iostream> #include <string> #include "share_ptr.h"using namespace std;int main(){{share_ptr<string> ps( new string("hello world") );cout << *ps <<" count:"<< ps.count() << endl;share_ptr<string> ps2(ps);cout << *ps2 <<" count:"<< ps2.count() << endl;share_ptr<string> ps3 = ps;cout << *ps3 <<" count:"<< ps2.count() << endl;ps2 = ps3;cout << *ps2 <<" count:"<< ps2.count() << endl;}system("pause");return 0; }
?