劍指Offer之賦值運算子函式解析

2021-07-26 06:06:05 字數 2008 閱讀 5604

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

class cmystring

首先對於c++乙個類中的6個預設的函式分別是構造,拷貝構造,賦值運算子過載,析構,以及取位址操作符過載以及const修飾的取位址操作符過載

對於拷貝構造以及賦值運算子過載,預設的使用是淺拷貝,也就是說將該物件的記憶體原封不動地挪動到新物件的記憶體中,因此對於含有指標的類,我們往往需要自己實現copying的操作來完成深拷貝(除非你就需要以淺拷貝的方式完成該操作),否則很有可能造成有多個指標指向同一塊空間,在析構時候同一塊空間析構多次導致崩潰。

常用的解決辦法是重新分配記憶體並拷貝或者實現引用計數版本,對於此題,我們選擇前者。

我給出的**如下:

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

return *this;

}

因為之前模擬寫過string類的簡單實現,所以我想了一下,就寫了上面的**。在這裡,幾個值得注意的點:

1. 賦值運算子的過載函式的宣告,需要返回型別的引用,也就是cmystring&,這裡是為了考慮到形如 a = b = c這樣的連續賦值操作,因此需要在函式結束前加上return *this;

2. 函式傳參需要引用,這樣避免了呼叫一次拷貝建構函式提高效率,同時為了不改變傳入例項,需要加上const

3. 重新分配記憶體時候,必須要釋放之前自己已有的空間,否則會導致記憶體洩漏

4. 要考慮到自己賦值給自己,即this == &other時候,其實不需要執行任何操作,同時更為重要的是:對於我自己寫的**如果不加上if (this != &other)**就是錯的,因為我是先釋放記憶體再根據other需要的空間開闢一塊新空間,對於自己賦值給自己的情況,由於已經自己指向的那塊空間已經釋放了,所以再也找不到需要賦值的內容了。

寫完對照書發現和書上大差不離。。嗯,適合初級程式設計師,不過想了想我這現在水平估計還不如初級呢(一臉懵逼,哈哈哈,下面看看書上是怎麼給出了考慮異常安全性的的解法

對於我之前寫的**,我是先釋放之前的記憶體再開闢新空間,如果此時記憶體不足導致new時丟擲異常,那麼此時m_pdata已經為空指標,容易導致程式崩潰,這樣違背了異常安全性(exception safety)的原則,因此可以採用先分配新空間,分配成功後再釋放原來的內容,當然書上給出了乙個更好的方法,先建立乙個臨時例項,再交換臨時例項和原來的例項。**如下:

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

return *this;

}

更好的辦法:

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

return *this;

}

在這個函式中,我們建立了乙個臨時物件temp,然後交換了temp.m_pdata和m_pdata指向的空間,此時temp指向的空間即為m_pdata之前的空間,由於temp是個區域性物件,執行到if作用域外,就用自動呼叫temp的析構函式從而完成了記憶體的釋放,同時也完成了相應的拷貝工作。**也簡潔的多,確實是個更好的辦法。當然我覺得,**可以在此基礎上更簡便一點:

cmystring& cmystring::operator=(cmystring other)

這樣寫需要改變引數的傳參,傳值而非引用,由於傳值時這個引數僅僅只是呼叫者的乙份拷貝(不用考慮自己給自己的情況),相當於上面建立臨時物件,此時交換析構原理和上面基本類似不再贅述。

劍指Offer 賦值運算子函式

按照自己淺薄的理解,敲了如下 include using namespace std class cmystring 就是定義了!cmystring char m pchar null cmystring const cmystring other cmystring cmystring opera...

劍指offer 賦值運算子函式

題目 如下為型別cmystring的宣告,請為該型別新增賦值運算子函式 class cmystring 思路 類的定義和基本形式 類其實是定義乙個特殊的資料結構,定義了類的物件包括了什麼,以及可以在這個物件上執行哪些操作 class student 成員函式定義 student student vo...

劍指offer 賦值運算子過載

還是有很多點需要注意的。判斷this與傳入的object是否是同乙個物件,相同的話直接返回 this就可以了。判斷傳入物件的陣列是否為空,空的話就不必複製,直接釋放記憶體並將指標置null即可。考慮異常安全。因為new char時如果記憶體不足會丟擲異常,這時安全的做法是先嘗試申請記憶體,申請成功後...