賦值運算子函式的**需要關注幾點
1) 是否把返回值的型別宣告為該型別的引用,並在函式結束前返回例項自身的引用(即*this)。只有返回乙個引用,才可以允許連續賦值。否則如果函式的返回值void,該賦值運算子將不能做連續賦值。
2) 是否把傳入的引數的型別宣告為常量引用。引數宣告為引用可以避免無謂的消耗,提高**的效率。同時我們希望賦值運算子函式內不會改變傳入的例項的狀態。因此應該為傳入的引用引數加上const關鍵字。
3) 是否釋放例項自身已有的記憶體。如果我們忘記在分配新記憶體之前釋放自身已有的空間,程式將出現記憶體洩露。
4) 是否判斷傳入的引數和當前的例項(*this)是不是為同一例項。如果是同乙個,則不進行賦值操作,直接返回。如果事先不判斷就進行賦值,當*this和傳入的引數是同乙個例項時,那麼一旦釋放了自身的記憶體,傳入的引數的記憶體也同樣被釋放了,因此再也找不到需要賦值的內容。
cmystring& operator=(constcmystring& str)
return*this;
}
但是這個函式有乙個缺陷,在分配記憶體之前先用delete釋放了例項m_pdata的記憶體。如果此時記憶體不足導致new char丟擲異常,m_pdata將是乙個空指標,這樣非常容易導致程式崩潰。也就是說一旦在賦值運算子函式內部丟擲乙個異常,cmystring的例項不再保持有效狀態,這就違背了異常安全性原則。
書中提出了乙個很新穎的方式,建立乙個臨時例項,再交換臨時例項和原來的例項。
cmystring&operator=(const cmystring& str)
return*this;
}
在這個函式中,我們先建立乙個臨時temp,接著把temp.m_pdata和自身的m_pdata做交換。由於temp是個區域性變數,但程式執行到if的外面也就出了該變數的作用域,就會自動呼叫temp的析構函式,把temp所指向的記憶體釋放掉。由於temp.m_pdata指向的記憶體就是例項之前m_pdata的記憶體,相當於自動呼叫析構函式釋放記憶體
給出cmystring類的完整**
class cmystring
else
}cmystring(constcmystring& str)
~cmystring()
/*cmystring&operator=(const cmystring& str)
return*this;
}*/cmystring&operator=(const cmystring& str)
return*this;
}private:
char*m_pdata;
};
賦值運算子函式
題目 如下為型別cmystring的宣告,請為該型別新增賦值運算子函式。class cmystring 1 經典解法,初級程式設計師 cmystring cmystring operator const cmystring str 2 考慮異常安全的解法,高階程式設計師 cmystring cmys...
賦值運算子函式
型別宣告如下 class cmystring 請為上型別新增賦值運算子函式.經典解法 cmystring cmystring operator const cmystring str 考慮異常安全性解法 cmystring cmystring operator const cmystring str...
賦值運算子函式
賦值運算子函式作為類的乙個成員函式,主要用於物件之間的賦值。類一般都有預設的賦值運算子函式,然而預設賦值運算子函式只會淺拷貝,無法滿足需求,有時還會產生致命錯誤。如下 class cstring cstring const cstring str buf nullptr cstring const ...