string型別過載賦值運算子

2021-10-07 08:52:14 字數 1313 閱讀 4525

cmystring& cmystring::operator = (const cmystring &str)
上述**有四點需要注意:

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

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

3.在重新賦值前先釋放自身已有的記憶體,如果在分配新記憶體之前沒有釋放自已有的空間,程式將會出現記憶體洩漏.

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

上述解法能全面考慮四點並完成寫出**已經不錯了,再看看下面的解法

在前面函式中,我們在分配記憶體之前先用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做交換,由於stetemp是乙個區域性變狼,當程式執行到if的外面時也就出了該變數的作用域,就會自動呼叫strtemp的析構函式,把stetemp.m_pdata所指向的記憶體釋放掉,由於stetemp.m_pdata指向的記憶體就是例項之前m_pdata的記憶體,這就相當於自動呼叫析構函式釋放例項的記憶體.

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

運算子過載 賦值運算子的過載

有時候希望賦值運算子兩邊的型別可以不匹配,比如,把乙個int型別變數賦值給乙個complex物件,或把乙個 char 型別的字串賦值給乙個字串物件,此時就需要過載賦值運算子 注意 賦值運算子 只能過載為成員函式 賦值運算子過載例項示例 include include using namespace ...

過載賦值運算子

1 注意過載賦值運算子和,運算子必須定義為類的成員函式。2 注意 如果程式不提供顯示的賦值運算子則系統會提供乙個預設的賦值運算子。3 什麼時候過載賦值運算子 當類中含有指標成員時,一般都要重定義類的賦值運算子。4 過載賦值運算子時應有處理語句m m的情況。其中m是某乙個類的物件。如果不處理這樣的語句...

賦值運算子過載

在下面類中實現 class cmystring 為了寫出乙個完整的賦值運算子過載函式,我們要考慮以下幾個問題 一步步解決上述的問題,我們可以編寫出經典的演算法 cmystring cmystring operator const cmystring str return this 考慮到異常安全性的...