赋值运算符函数严谨性的几点思考
生活随笔
收集整理的這篇文章主要介紹了
赋值运算符函数严谨性的几点思考
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1. 需求
class CMyString { public:CMyString(char* pData = NULL);CMyString(const CMyString& str);~CMyString(void); private:char* m_pData; };2.定義賦值運(yùn)算符函數(shù)需要考慮的四個準(zhǔn)則
- 是否把返回值的類型聲明為該類型的引用,并在函數(shù)結(jié)束前返回實例自身的引用(即*this)。只有返回一個引用,才可以允許連續(xù)的賦值。否則如果該函數(shù)的返回值是void,應(yīng)用該賦值運(yùn)算符不能做連續(xù)的賦值。假設(shè)有3個連續(xù)的CMyString對象:str1=str2=str3,將不能編譯通過。
- 是否把傳入的參數(shù)類型生命為常量引用。如果傳入的參數(shù)不是引用而是實例,那么從形參到實參會調(diào)用一次復(fù)制構(gòu)造函數(shù)。辦參數(shù)聲明為引用可以避免這樣的無謂的消耗,從而提高代碼的效率。同時,我們在賦值運(yùn)算符函數(shù)內(nèi)不會改變差UN入的實例的狀態(tài),因此應(yīng)該為傳入的引用參數(shù)加上const關(guān)鍵字。
- 是否釋放實例自身已有的內(nèi)存。如果我們在分配新內(nèi)存之前,忘記了釋放自身已有的空間,程序?qū)l(fā)生內(nèi)存泄漏。
- 是否判斷傳入的參數(shù)與當(dāng)前的實例(*this)是不是同一個實例。如果是同一個,則沒有必要進(jìn)行復(fù)制操作,直接返回當(dāng)前實例的指針。如果事前不判斷就進(jìn)行賦值,那么在釋放實例自身的內(nèi)存的時候就會導(dǎo)致嚴(yán)重的錯誤:當(dāng)*this和傳入的參數(shù)是同一個實例時,一旦釋放了自身的內(nèi)存,傳入的參數(shù)的內(nèi)存也被同時釋放,因此再也找不到需要復(fù)制的內(nèi)容了。
3.初級程序員的解法
CMyString& CMyString::operator =(const CMyString& str) //返回類型為該類型的引用 //形參類型聲明為類型的常量引用 {if(this == &str) // 判斷傳進(jìn)來的實例與當(dāng)前是否為同一個實例return *this;delete [] m_pData; // 清除當(dāng)前實例的內(nèi)存,并重新分配m_pData = NULL;m_pData = new char [strlen(str.m_pData)+1];strcpy(m_pData, str.m_pData);return *this; // 函數(shù)結(jié)束前返回自身的引用 }4.高級程序員的解法_異常安全性原則
在3中,我們在分配內(nèi)存之前先用delete釋放了實例m_pData的內(nèi)存。如果私事內(nèi)存不足導(dǎo)致new char拋出異常,m_pData將是一個空指針,這樣非常容易導(dǎo)致程序崩潰。也就是說,一旦在賦值運(yùn)算符函數(shù)內(nèi)部剖出一個異常,CMyString的實例不在保持有效的狀態(tài),這就違背了一場安全性(Exception Safety)原則。
要想在賦值運(yùn)算符函數(shù)中實現(xiàn)異常安全性,有兩種方法。一個簡單的方法是我們先用new分配新內(nèi)容在用delete釋放已有的內(nèi)容。這樣只有在分配內(nèi)存成功之后才會釋放原來的內(nèi)容,也就是就是內(nèi)存可能會分配失敗,但我們也能確保CMyString實例不被修改。其實,在這里我更建議先創(chuàng)建一個臨時實例,在交換臨時實例和原來的實例。
代碼如下:
CMyString& CMyString::operator = (const CMyString &str) {if(this != &str){CMyString strTemp(str);char* pTemp = strTemp.m_pData;strTemp.m_pData = m_pData;m_pData = pTemp;}return *this; }在這個函數(shù)中,我們先創(chuàng)建了一個臨時實例strTemp,接著把strTemp.m_pData和實例自身的m_pData作交換。由于strTemp是一個局部變量,當(dāng)程序運(yùn)行到if之外的時候,就會自動調(diào)用strTemp的析構(gòu)函數(shù),把strTemp.m_pData指向的內(nèi)存釋放掉。由于strTemp.m_pData指向的內(nèi)存就是實例之前的m_pData的內(nèi)存,相當(dāng)于自動調(diào)用析構(gòu)函數(shù)釋放實例的內(nèi)存。 與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的赋值运算符函数严谨性的几点思考的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 体验微软反间谍软件及恶意软件清除工具
- 下一篇: BCB窗体移动