- 必須維護的約束條件
- 決定了你的成員函數必須進行的錯誤檢查工作
- 影響函數拋出的異常
- 函數異常明細列表
Effective C++(19) 設計class猶如設計type
問題聚焦:
這一節不涉及代碼,但是我們需要明確的一點是,思想比代碼要重要得多。
設計優秀的classes是一項艱鉅的工作,就像設計好的types一樣。
我們應該帶着和“語言設計者當初設計語言內置類型時”一樣的謹慎來研討class的設計。
那麼,如何設計高效的classes呢?
下面幾乎每一個針對class設計的提問,往往就是你所需要遵守的設計規範。
1 新type的對象應該如何被創建和銷燬?
這會影響到你的class的構造函數和析構函數以及內存分配函數和釋放函數的設計。
2 對象的初始化和對象的賦值該有什麼樣的差別?
這個答案決定你的構造函數和賦值操作符的行爲,以及其間的差異。
很重要的一點:別混淆了“初始化”和“賦值”,因爲它們對應於不同的函數調用。
3 新type的對象如果被passed by value,意味着什麼?
記住,拷貝構造函數用來定義一個type的pass-by-value該如何實現。
4 什麼是新type的合法值?
對class的成員變量而言,通常只有某些值集是有效的。
那些值集決定了你的class:
如果你繼承自某些既有的classes,你就受那些classes的設計的束縛,特別是受到它們的函數是virtual或non-virtual的影響。
如果你允許其他classes繼承你的class,那會影響你所聲明的函數,尤其是析構函數。
6 你的新type需要什麼樣的轉換?
你的type生存於其他一堆types之間,因此彼此該有轉換行爲嗎?
如果你希望允許類型T1被隱式轉換爲類型T2,就必須在class T1內寫一個類型轉換函數或在class T2內寫一個non-explicit-one-arument的構造函數。
7 什麼樣的操作符和函數對此新type而言是合理的?
這個問題的答案決定你將爲你的class聲明哪些函數。其中某些該是member函數,某些則不是。
8 什麼樣的標準函數應該被駁回?
那些正是你必須聲明爲private的函數。
9 誰該取用新type的成員?
這個提問可以幫你你決定哪個成員爲public,哪個爲protected,哪個爲private。
它也幫助你決定哪一個classes和/或functions應該是friends,以及將它們嵌套於另一個之內是否合理。
10 什麼是新type的“未聲明接口”?
它對效率,異常安全性以及資源運用提供何種保證?
你在這些方面提供的保證將成爲你的class實現代碼加上相應的約束條件。
11 你的新type有多麼一般化?
或許你其實並非定義一個新type,而是定義個整個types家族。果真如此,你就不應該定義一個新class,而是應該定義一個新的class template。
12 你真的需要一個新type嗎?
如果只是定義新的derived class 以便爲既有的class 加機能, 那麼說不定單純定義一或多個non-member函數或templates,更能打到目標。
這些問題不容易回答,所以定義出高效的classes是一種挑戰。
小結:
class 的設計就是type的設計。
在定義一個新type或class之前,請認真考慮本節的12個問題。
參考資料:
《Effective C++ 3rd》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.