讀書筆記 effective c++ Item 19 像設計類型(type)一樣設計類。本站提示廣大學習愛好者:(讀書筆記 effective c++ Item 19 像設計類型(type)一樣設計類)文章只能為提供參考,不一定能成為您想要的結果。以下是讀書筆記 effective c++ Item 19 像設計類型(type)一樣設計類正文
1. 你需要重視類的設計
c++同其他面向對象編程語言一樣,定義了一個新的類就相當於定義了一個新的類型(type),因此作為一個c++開發人員,大量時間會被花費在擴張你的類型系統上面。這意味著你不僅僅是一個類的設計者同時是一個類型設計者。重載函數和運算符,控制內存分配和釋放,定義對象初始化和終結,這些都是你需要考慮的。因此你應該同語言設計者一樣,它們將時間浪費在內建類型的設計上,你就應該對類的設計施以同樣的關注。
2. 高效的類型的特征
設計好的類很具有挑戰性,因為設計好的類型具有挑戰性。好的類型有自然的語法,直觀的語義和一種或多種高效的實現。在c++中,沒有計劃好的類定義將不能達到上述任何目標。甚至一個類的成員函數的聲明方式都可能會影響到成員函數的性能。
3. 在設計一個類時,你需要問自己的若干問題
因此你怎麼才能設計一個高效的類呢?首先,你必須理解你所面對的問題。幾乎每個類都需要你面對下面的問題,這些問題的答案常常會約束你的設計:
- 新類型的對象應該怎麼被創建和釋放?如何做將影響著類的構造函數和析構函數的設計,同樣影響內存分配和釋放函數(運算符new[],運算符 delete,和運算符delete[]看第8章)的設計。
- 對象初始化同對象賦值怎麼不一樣?這個問題的回答決定了你的構造函數和賦值運算符的行為,以及它們之間的區別。分清楚初始化和賦值很重要,因為他們對應著不同的函數調用(見Item 4)。
- 如果你的新類型對象被當作按值傳遞的參數會意味著什麼?記住,拷貝構造函數定義了一個類型的按值傳遞該如何實現。
- 你的新類型在值的合法性上是如何進行限制的?一般情況下,對於一個類的數據成員來說,只有值的一些組合才是有效的。這些組合決定你的類必須維持不變性(invariants)。這些不變性就決定了你必須在你的成員函數內部做錯誤檢查,特別是在你的構造函數,賦值運算符和”setter”函數中。這也同樣影響函數拋出的異常,以及函數的exception specifications(你可能很少使用)。
- 你的新類型需要配合某個繼承圖中麼?如果你的類從現存的類繼承而來,你就會受這些類設計的束縛,特別是受函數是virtual還是非virtual的束縛(Item 34和Item 36)。如果你希望別的類能繼承自你的類,就會影響你的聲明的函數應該是不是虛函數,特別是析構函數(Item 7)
- 你的新類型允許何種類型轉換?你的類型會被淹沒在其他類型之中,那麼應該在你的類型和其他類型之間做轉換麼?如果你希望允許類型T1的對象隱式轉換成T2類型的對象,你要麼在類T1中寫一個類型轉換函數(例如,operator T2)要麼在類T2中寫一個non-explicit的單參數構造函數。如果你只希望進行顯示轉換,就需要寫出執行轉換的函數,但是需要防止這種轉換調用類型轉換操作符或者non-explicit單參數構造函數。(隱式轉換和顯示轉換的例子,見Item 15)
- 對於新類型來說什麼樣的運算符和函數才是有意義的?你對這個問題的回答決定了你會為你的類聲明哪些函數。一些函數會是成員函數,但是另外一些不是(Item 23,Item 24,Item 46)。
- 什麼樣的標准函數應該被禁止?你應該將這樣的函數聲明成private(Item 6)
- 誰對你的新類型的成員有訪問權?這個問題幫助你決定哪些成員是public的,哪些是protected,哪些是private的。它同樣幫助你決定哪些類和函數應該是friend的,還有把一個類內嵌入另一個類是否有意義。
- 你的新類型的“未定義接口”是什麼?對於性能,異常安全(Item 29)和資源的使用(比如鎖和動態內存),你提供了什麼樣的保證?在這些領域中你所提供的保證將會對你的類實現強加限制。
- 你的新類型有多普遍?可能你沒有定義一個新的類型。你在定義一整個類型族。如果是這樣,你不需要定義一個新類,你需要的是一個新的類模版。
- 這個新類型真的是你想要的麼?如果定義一個新的派生類只是為了在這個類中添加新的功能,那麼為了達到你的目標,簡單的定義一個或者多個非成員函數或者模板會可能是較好的選擇。
這些問題很難回答,所以定義高效的類很具挑戰性。做好它吧,至少使得c++中自定義類產生的類型同內建類型一樣好,達到這麼目標,所有努力都值得。