C++給用戶充分申請和釋放的能力,當時指針使用不當很容易傷手。尤其是在類中使用指針時,很容易發生忘記釋放內存造成的內存洩露,和釋放已經釋放的內存造成的指針錯誤。為此需要使用一種指針引用計數的智能指針來管理指針的使用。
首先對要作為指針的對象,添加一個管理類,此類保存著類的對象(注意這裡是原始類的對象)和使用次數,此類完全是為了保存原始類的一個對象副本,後續無論是拷貝構造還是復制引用都維持一份指針副本。根據實際需要也可是實現深拷貝,每個都維持一個副本。目前實現的是淺拷貝,大家都是一個副本。
代碼如下
要作為指針的類
/***************** 最原始的點類實現 ******************/ class Point { public: Point():m_x(0),m_y(0){}; Point(int x,int y):m_x(x),m_y(y){}; ~Point(){cout<<"Point 類被析構了"<<endl;}; void SetX(int x); void SetY(int y); int GetX(); int GetY(); string m_PointName; private: int m_x; int m_y; }; void Point::SetX(int x) { this->m_x = x; } void Point::SetY(int y) { this->m_y = y; } int Point::GetX() { return this->m_x; } int Point::GetY() { return this->m_y; }
記錄指針對象的類
//前向聲明,表明後面要定義這個類 class SmartPoint; /************************************ 指針管理類,此類實現是為了 記錄有指針被多少對象使用 *************************************/ class UPoint { //此類的所有成員和變量都是私有的,為的就是只能被智能指針所使用 private: //此處將智能指針類定義為友元,可以訪問此類的私有成員 friend class SmartPoint; UPoint():m_iUse(1){}; UPoint(int x,int y):m_Point(x,y),m_iUse(1){}; UPoint(const Point &tPoint):m_Point(tPoint),m_iUse(1){}; //注意這裡保存的是對象,不是指針,是要 //記錄使用次數的指針 Point m_Point; int m_iUse; };
對象指針的具體實現智能指針
/******************************* 智能指針實現類 ********************************/ class SmartPoint { public: SmartPoint():m_UPoint(new UPoint()){}; SmartPoint(int x,int y):m_UPoint(new UPoint(x,y)){}; SmartPoint(const Point &tPoint):m_UPoint(new UPoint(tPoint)){}; //拷貝構造和復制操作符 SmartPoint(const SmartPoint &tSmartPoint); SmartPoint& operator =(const SmartPoint &tSmartPoint); ~SmartPoint(); void SetX(int x); void SetY(int y); int GetX(); int GetY(); void SetName(string sName); void ShowInfo(); private: //注意這裡定義的是一個指針,所有的智能指針指向同一對象 //只有引用計數為0時才會釋放這個指針 UPoint *m_UPoint; }; //--------------------------------------------------------------------------- SmartPoint::~SmartPoint() { --this->m_UPoint->m_iUse; cout<<"智能指針類析構函數調用了 剩余次數"<<this->m_UPoint->m_iUse<<endl; if(0 == this->m_UPoint->m_iUse) { cout<<"智能指針監視的指針被釋放了"<<endl; delete this->m_UPoint; } } /***************************************** 拷貝構造函數 *****************************************/ SmartPoint::SmartPoint(const SmartPoint &tSmartPoint) { //指針淺拷貝,指向同一個副本 this->m_UPoint = tSmartPoint.m_UPoint; //增加使用計數 ++this->m_UPoint->m_iUse; } /******************************************** 復制構造函數 *********************************************/ SmartPoint& SmartPoint:: operator =(const SmartPoint &tSmartPoint) { cout<<"復制操作符執行了"<<endl; //增加右側的計數 ++tSmartPoint.m_UPoint->m_iUse; //減少左側的計數,如果左側已經為0,釋放該指針 --this->m_UPoint->m_iUse; if(0 == this->m_UPoint->m_iUse) { delete this->m_UPoint; } //指針淺拷貝,指向同一個副本 this->m_UPoint = tSmartPoint.m_UPoint; return *this; }
測試代碼
int main(int argc, char* argv[]) { class SmartPoint *ASmartPoint = new SmartPoint(); ASmartPoint->SetName("Class A"); ASmartPoint->ShowInfo(); //拷貝構造 class SmartPoint *BSmartPoint= new SmartPoint(*ASmartPoint); BSmartPoint->ShowInfo(); class SmartPoint *CSmartPoint = new SmartPoint(); //復制構造 *CSmartPoint = *BSmartPoint; ASmartPoint->ShowInfo(); delete ASmartPoint; BSmartPoint->ShowInfo(); delete BSmartPoint; CSmartPoint->ShowInfo(); delete CSmartPoint; char c; cout<<"輸出任意鍵退出........."<<endl; c = getchar(); return 0; }
測試結果
本文出自 “風清揚song” 博客,請務必保留此出處http://2309998.blog.51cto.com/2299998/1303180