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:
  •     必須維護的約束條件
  •     決定了你的成員函數必須進行的錯誤檢查工作
  •     影響函數拋出的異常
  •     函數異常明細列表
5 你的新type需要配合某個繼承圖系嗎?
    如果你繼承自某些既有的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》
發佈了95 篇原創文章 · 獲贊 45 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章