c 實現的string類

2021-07-26 00:06:09 字數 1528 閱讀 8710

普通版

class string

else

}//拷貝建構函式

string(const string& str) //引數為引用,如果為值的話 可能無限呼叫拷貝構造陷入死迴圈

:_pstr(new char[strlen(str._pstr) + 1])

//賦值過載函式

string& operator=(const string& str) //返回值為引用:可以實現連續賦值

//引數:如果為例項不是引用,呼叫拷貝建構函式,減少消耗

return *this;

} ~string() }

private:

char* _pstr;

};

注意:

在賦值運算子的過載函式中,如果不開闢臨時變數的話,可能存在的問題:

我們在記憶體分配new之前就delete釋放掉_pstr的記憶體,如果此時記憶體不足的話,可能導致new char丟擲異常,這樣的話,_pstr為一空指標,可能導致程式崩潰。也就是說一旦在賦值運算子過載函式中丟擲乙個異常,string的例項將不再保持有效狀態,這就違背了異常安全機制。

解決方法

(1)先new分配新內容,再delete釋放已有的內容。這樣只有在new成功後再釋放原來的記憶體,這樣能確保分配記憶體失敗後,string的例項不會被修改。

(2)建立乙個臨時例項,交換臨時例項和原來的例項。

//建立臨時變數:防止記憶體不足new char丟擲異常

string strtemp(str); //出了作用域 就釋放

//將_pstr與strtemp._pstr交換

char* ptemp = strtemp._pstr;

strtemp._pstr = _pstr; //把原資料賦值給臨時變數,出了作用域釋放掉

_pstr = ptemp; //把ptemp賦值給原資料

建立臨時例項,如果沒有丟擲異常,臨時例項出了if作用域,就會呼叫析構函式,釋放掉_pstr,而此時的臨時變數的_pstr 指向記憶體為原來變數的記憶體。這樣就相當於釋放掉例項的記憶體。

如果丟擲異常,此時我們還沒有修改原來例項的狀態,因此例項的狀態還是有效的,這樣就保證了異常安全性。

簡潔版

class string

else

}string(const string& str)

:_pstr(null) //防止交換後strtemp的_pstr指向隨機空間,導致記憶體洩漏

string& operator=(const string& str) }

~string() }

private:

char* _pstr;

};

C 中String類的實現

include include using namespace std class string else 拷貝建構函式 開闢跟源字串長度一樣長的空間給目標物件 string string s pstr new char strlen s.pstr 1 賦值運算子的過載 因為考慮到連續賦值的情況,故...

C 中String類的實現

原文 string是c 中的重要型別,程式設計師在c 面試中經常會遇到關於string的細節問題,甚至要求當場實現這個類。只是由於時間關係,可能只要求實現建構函式 析構函式 拷貝建構函式等關鍵部分。string的實現涉及很多c 的基礎知識 記憶體控制及異常處理等問題,仔細研究起來非常複雜,本文主要做...

C 中String類的實現

from string是c 中的重要型別,程式設計師在c 面試中經常會遇到關於string的細節問題,甚至要求當場實現這個類。只是由於時間關係,可能只要求實現建構函式 析構函式 拷貝建構函式等關鍵部分。string的實現涉及很多c 的基礎知識 記憶體控制及異常處理等問題,仔細研究起來非常複雜,本文主...