《劍指Offer》 試題1 賦值運算子函式

2022-01-23 16:32:50 字數 1303 閱讀 1105

題目:如下型別為cmystring的宣告,請為該型別新增賦值運算子函式。

class

cmystring

;

關注點:

1.是否把返回值的型別宣告為該型別的引用,並在函式結束前返回例項自身的引用(即*this)。只有返回乙個引用,才可以允許連續賦值(str1=str2=str3);

2.是否把傳入的引數的型別宣告為常量引用。如果傳入的的引數不是引用而是例項,那麼從形參到實參會呼叫一次複製建構函式。把引數宣告為引用可以避免這種無謂的消耗,提高**效率。同時,我們在賦值運算子函式內不會改變傳入例項的狀態,因此該為傳入的引用引數加上const關鍵字;

3.是否釋放例項自身已有的記憶體。如果我們忘記在分配新記憶體之前釋放自身已有的空間,程式將出現記憶體洩漏;

4.是否判斷傳入的引數和當前例項(*this)是不是同乙個例項。如果是同乙個,則不進行賦值操作,直接返回。如果事先不判斷就進行賦值那麼在釋放例項自身的記憶體的時候就會導致嚴重的問題。當*this和傳入的引數是同乙個例項時,那麼一旦釋放了自身的記憶體,傳入的引數的記憶體也同時被釋放了,因此再也找不到需要賦值的內容了。

解法一:經典的解法

當完整的考慮上述四個方面後,寫下如下**。

cmystring& cmystring::operator =(const cmystring&str)

delete

m_pdata;

m_pdata =null;

m_pdata = new

char[strlen(str.m_pdata) + 1

]; strcpy(m_pdata, str.m_pdata);

return *this

;}

解法二:考慮異常安全性

我們在分配記憶體之前先用delete釋放了例項m_pdata的記憶體。如果此時記憶體不足導致new char丟擲異常,m_pdata將是乙個空指標,這樣非常容易造成程式崩潰。要想在賦值運算子函式中實現異常安全性,有兩種方法。乙個簡單的辦法是我們先用new分配新內容再用delete釋放已有的內容。這樣只在分配內容成功之後再釋放原因的內容,也就是當分配記憶體失敗時我們能確保cmystring的例項不會被修改。還有乙個更好的辦法是先建立乙個臨時例項,再交換例項和原來的例項。

cmystring& cmystring::operator =(const cmystring&str)

return *this

;}

劍指offer 面試題1 賦值運算子函式

題目 如下為型別cmystring的宣告,請為該型別新增賦值運算子函式。class cmystring 當面試官要求應聘者定義乙個賦值運算子函式時,他對 會關注以下幾點 是否把返回值的型別宣告為該型別的引用,並在函式結束前返回例項自身的引用 即 this 只有返回乙個引用,才可以允許連續賦值。否則如...

劍指offer 面試題1 賦值運算子函式

題目要求為下面乙個類實現乙個賦值運算子的函式 class cmystring 我們要實現任意的乙個類的賦值運算子函式,都要注意一些方面 書上的解法給的確實很完備,而且後來用了一種巧妙的方法讓程式自動釋放記憶體。但我覺得重點是他提到的異常安全性的處理,這裡的話如果我們在new的時候記憶體不夠,而我們又...

《劍指Offer》面試題1 賦值運算子函式

要求 如下型別為cmystring的宣告,請為型別新增賦值運算子函式。class cmystring 測試用例 把乙個cmystring的例項賦值給另外乙個例項 把乙個cmystring的例項賦值給自己 連續賦值 本題考點 對c 基本語法的理解,如運算子過載 常量引用等。考查對記憶體洩漏的理解 對於...