1. 程式人生 > >繼承和麵向物件設計

繼承和麵向物件設計

繼承與面向物件設計

32. 確定你的public繼承塑模出is-a關係

  • "public繼承"意味is-a.適用於base classes身上的每一件事情一定也適用於derived classes身上,因為每一個derived class物件也都是一個base class物件

33. 避免遮掩繼承而來的名稱

  • derived classes 內的名稱會遮掩base classes 內的名稱.在public繼承下從來沒有人希望如此.
  • 為了讓被遮掩的名稱再見天日,可使用using 宣告式或轉交(forwardign functions).

34. 區別介面繼承和實現繼承

  • 介面繼承和實現繼承不同.在public繼承之下,derived classes 總得繼承base class的介面.
  • pure virtual函式只具體指定介面繼承
  • 簡樸的(非純)impure virtual 函式集體指定介面繼承集預設實現繼承
  • non-virtual 函式具體指定介面繼承以及強制性實現繼承

35. 考慮virtual函式以外的其他選擇

  • virtual 函式的替代方案包括NVI手法及Strategy設計模式的多種形式.NVI手法自身是一個特殊形式的Template Method設計模式.
  • 將機能從成員函式移到class外部函式,帶來一個缺點是,非成員函式無法訪問class 的non-public成員
  • trl::function 物件的行為就像一般函式指標.這樣的物件可接納"與給定之目標籤名式(target signature)相容"的所有可呼叫物(callable entities).

36.絕不重新定義繼承而來的non-virtual函式

  • 絕對不要重新定義繼承而來的non-virtual函式

37.絕不重新定義繼承而來的預設引數值

  • 絕對不要重新定義一個繼承而來的預設引數值,因為預設引數值都是靜態繫結,而virtual函式--你唯一應該覆寫的東西--卻是動態繫結

38.通過複合塑模出has-a 或"根據某物實現出"

  • 複合(composition)的意義和public繼承完全不同
  • 在應用域(application domain),複合意味著has-a(有一個).在實現域(implementation domain),複合意味is-implemented-in-terms-of(根據某物實現出)

39. 明智而審慎地使用private 繼承

  • private 繼承意味is-implemented-in-terms-of (根據某物實現出).它通過比複合(composition)的級別低.但是當derived class需要訪問protected base class的成員,或需要重新定義繼承而來的virtual函式時,這麼設計是合理的.
  • 和複合(composition)不同,private 繼承可以造成empty base 最優化.這對致力於"物件尺寸最小化"的程式庫開發者而言,可能很重要

40. 明智而審慎地使用多重繼承

  • 多重繼承比單一繼承複雜.它可能導致新的歧義性,以及對virtual繼承的需要

  • virtual 繼承會增加大小,速度,初始化(及賦值)複雜度等等成本.如果virtual base classes 不帶任何資料,將是最具實用價值的情況

  • 多重繼承的確與正當用途.其中一個情節設計"public 繼承某個Interface class"和"private 繼承某個協助實現的class"的兩相組合.