普通版
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 的基礎知識 記憶體控制及異常處理等問題,仔細研究起來非常複雜,本文主...