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

2021-07-13 07:54:28 字數 2365 閱讀 8946

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

class cmystring

;

當面試官要求應聘者定義乙個賦值運算子函式時,他對**會關注以下幾點:

* 是否把返回值的型別宣告為該型別的引用,並在函式結束前返回例項自身的引用(即*this)。只有返回乙個引用,才可以允許連續賦值。否則如果函式的返回值是void,應用該賦值運算子將不能做連續賦值。

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

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

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

完整的考慮了上述4個方面之後,就可以寫出如下**:

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

考慮安全性的解法,高階程式設計師必備

在前面的函式中,我們在分配記憶體之前先用delete釋放了例項m_pdata的記憶體。如果此時記憶體不足導致new char丟擲異常,m_pdata將是乙個空指標,這樣非常容易導致程式崩潰。也就是說一旦在賦值運算子函式內部丟擲乙個異常,cmystring的例項不再保持有效的狀態,這就違背了異常安全性原則。

要想在賦值運算子函式中實現異常安全性,我們有兩種方法。乙個簡單的辦法是我們先用new分配新內容再用delete釋放已有的內容。這樣只在分配內容成功之後再釋放原來的內容,也就是當分配記憶體失敗時我們能確保cmystring的例項不會被修改。我們還有乙個更好的辦法是先建立乙個臨時例項,再交換臨時例項和原來的例項。下面是這種思路的參考**:

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

return *this;

}

在這個函式中,我們先建立乙個臨時例項strtemp,接著把strtemp.m_pdata和例項自身的m_pdata做交換。由於strtemp是乙個區域性變數,但程式執行到if的外面時也就出了該變數的作用域,就會自動呼叫strtemp的析構函式,把strtemp.m_pdata所指向的記憶體釋放掉,由於strtemp.m_pdata所指向的記憶體就是例項之前m_pdata的記憶體,這就相當於自動呼叫析構函式釋放例項的記憶體。

在新的**中,我們在cmystring的建構函式裡用new分配記憶體。如果由於記憶體不足丟擲異常,我們還沒有修改原來例項的狀態,因此例項的狀態還是有效的,這也就保證了異常安全性。

源**:

#include "stdafx.h"

#include class cmystring

;cmystring::cmystring(char *pdata)

else

}cmystring::cmystring(const cmystring &str)

cmystring::~cmystring()

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

// ********************測試**********************

void cmystring::print()

void test1()

// 賦值給自己

void test2()

// 連續賦值

void test3()

int _tmain(int argc, _tchar* argv)

測試用例:

* 把乙個cmystring的例項賦值給另外乙個例項

* 把乙個cmystring的例項賦值給它自己

* 連續賦值

輸出結果:

本題考點:

* 考查對c++的基礎語法的理解,如運算子函式、常量引用等。

* 考查對記憶體洩漏的理解。

* 對高階c++程式設計師,面試官還將考查應聘者對**異常安全性的理解。

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

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

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

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

劍指Offer 面試題1(賦值運算子函式)

生活有種律動,須有光有影,有左右有,有晴有雨,滋味就含在這變而不猛的曲折裡.老舍 題目描述 如下為型別cmystring的宣告,請為該型別新增賦值運算子函式。class cmystring 題目解析 對於定義乙個賦值運算子函式時,需要考慮 1.是否把返回值的型別宣告為該型別的引用,並在函式結束前返回...