class design checklist
- 你需要一個建構子嗎?
想一下。
- 你的成員變數是私有的嗎?
1. 定義域、值域的程式化。ex: length的長度一定要大於零。
2. 算式表示抽象屬性。ex: vector<int>::length(); 元素的數量是取值時才運算出來的。
- 你的類別需要一個無參數的建構子嗎?
- 是不是每個建構子都初始化所有的成員變數呢?
這問題是刺激你思考是否都盡可能的初始化了。
- 類別需要解構子嗎?
1. 這個類別要做些什麼
2. 是否有不會由成員函數自動釋放的動態記憶體空間
通常,建構子有new出什麼動態記憶體配置,解構子就要delete
- 類別需要一個虚擬解構子嗎?
- 你的類別需要自己寫一個複製建構子嗎?
如果有動態記憶體宣告的空間,就考慮是否要複製建構子。
- 你的類別需要自己寫一個賦值運算子嗎?
注意返回值要 X& X::operator=(),並且 return *this;
- 你的賦值運算子能正確的將物件賦值給物件嗎?
賦值總是用新的值取代舊的值,但是如果「來源物件與目標物件是同一個」,就不可以奉行「先釋放舊值,再複製新值」,會先毀掉來源物件裡的值。
在這,有兩個作法
1. 判斷是不是賦值給自己,再決定是不是要delete
xString$ xString::operator=(const xString& xstr)
{
if (&s != this)
{
delete [] data;
data = new char[strlen(s.data) + 1];
strcpy(data, s.data);
}
return *this;
}
2. 先暫存,再賦值,最後再delete
xString$ xString::operator=(const xString& xstr)
{
char* newdata = new char[strlen(s.data) + 1];
strcpy(newdata, s.data);
delete [] data;
data = newdata;
return *this;
}
- 你的類別需要關係運算子嗎?
- 刪除陣列時你記得使用delete[]嗎?
- 記得在複製建構子和賦值運算子的參數加上const了嗎?
提供保證,複製物件並不會改變原物件。
- 如果函數的參數是參考,它們是否該加上const?
只有當函數想改變參數時,才會取消加上const
- 記得適當的宣告成員函數成const了嗎?