封裝可以使得代碼模塊化,繼承可以擴展已存在的代碼,他們的目的都是為了代碼重用。而多態的目的則是為了接口重用
-
封裝:封裝是在設計類的一個基本原理,是將抽象得到的數據和行為(或功能)相結合,形成一個有機的整體,也就是將數據與對數據進行的操作進行有機的結合,形成“類”,其中數據和函數都是類的成員。
-
繼承:如果一個類別B“繼承自”另一個類別A,就把這個B稱為“A的子類”,而把A稱為“B的父類別”也可以稱“A是B的超類”。繼承可以使得子類具有父類別的各種屬性和方法,而不需要再次編寫相同的代碼。在令子類別繼承父類別的同時,可以重新定義某些屬性,並重寫某些方法,即覆蓋父類別的原有屬性和方法,使其獲得與父類別不同的功能。
-
訪問權限
- public: 父類對象內部、父類對象外部、子類對象內部、子類對象外部都可以訪問。
- protected:父類對象內部、子類對象內部可以訪問,父類對象外部、子類對象外部都不可訪問。
- private:父類對象內部可以訪問,其他都不可以訪問。
|訪問對象|public|protected|private|
|-|-|-|-|
|父類|可見|可見|可見|
|子類|可見|可見|不可見|
|父類外部|可見|不可見|不可見|
|子類外部|可見|不可見|不可見| -
繼承方式
ps.三種繼承方式不影響子類對父類的訪問權限,子類對父類只看父類的訪問控制權。繼承方式是為了控制子類(也稱派生類)的調用方(也叫用戶)對父類(也稱基類)的訪問權限。public、protected、private三種繼承方式,相當於把父類的public訪問權限在子類中變成了對應的權限。 如protected繼承,把父類中的public成員在本類中變成了protected的訪問控制權限;private繼承,把父類的public成員和protected成員在本類中變成了private訪問控制權。ps.友元是類級別的,不存在繼承的問題。
-
-
多態:多態性可以簡單地概括為“一個接口,多種方法”,程序在運行時才決定調用的函數,它是面向對象編程領域的核心概念。多態(polymorphism),字面意思多種形狀。
-
靜態多態:靜態多態也稱為靜態綁定或早綁定。編譯器在編譯期間完成的,編譯器根據函數實參的類型(可能會進行隱式類型轉換),可推斷出要調用那個函數,如果有對應的函數就調用該函數,否則出現編譯錯誤。
-
函數重載
編譯器根據函數不同的參數表,對同名函數的名稱做修飾,然后這些同名函數就成了不同的函數(至少對於編譯器來說是這樣的)。函數的調用,在編譯器間就已經確定了,是靜態的。也就是說,它們的地址在編譯期就綁定了(早綁定)。
-
泛型編程
泛型編程就是指編寫獨立於特定類型的代碼,泛型在C++中的主要實現為模板函數和模板類。
泛型的特性:1. 函數模板並不是真正的函數,它只是C++編譯生成具體函數的一個模子。 1. 函數模板本身並不生成函數,實際生成的函數是替換函數模板的那個函數,比如上例中的add(sum1,sum2),這種替換是編譯期就綁定的。 3. 函數模板不是只編譯一份滿足多重需要,而是為每一種替換它的函數編譯一份。 4. 函數模板不允許自動類型轉換。 5. 函數模板不可以設置默認模板實參。比如template <typename T=0>不可以。
-
-
動態多態
c++的動態多態是基於虛函數的。對於相關的對象類型,確定它們之間的一個共同功能集,然后在基類中,把這些共同的功能聲明為多個公共的虛函數接口。各個子類重寫這些虛函數,以完成具體的功能。客戶端的代碼(操作函數)通過指向基類的引用或指針來操作這些對象,對虛函數的調用會自動綁定到實際提供的子類對象上去。 -
宏多態(?)
帶變量的宏可以實現一種初級形式的靜態多態:#include <iostream> #include <string> // 定義泛化記號:宏ADD #define ADD(A, B) (A) + (B); int main() { int i1(1), i2(2); std::string s1("Hello, "), s2("world!"); int i = ADD(i1, i2); // 兩個整數相加 std::string s = ADD(s1, s2); // 兩個字符串“相加” std::cout << "i = " << i << "/n"; std::cout << "s = " << s << "/n"; }
-
動態多態和靜態多態的比較
- 靜態多態
- 優點:
- 由於靜多態是在編譯期完成的,因此效率較高,編譯器也可以進行優化;
- 有很強的適配性和松耦合性,比如可以通過偏特化、全特化來處理特殊類型;
- 最重要一點是靜態多態通過模板編程為C++帶來了泛型設計的概念,比如強大的STL庫。
- 缺點:
- 由於是模板來實現靜態多態,因此模板的不足也就是靜多態的劣勢,比如調試困難、編譯耗時、代碼膨脹、編譯器支持的兼容性不能夠處理異質對象集合
- 優點:
- 動態多態
- 優點:
- OO設計,對是客觀世界的直覺認識;
- 實現與接口分離,可復用
- 處理同一繼承體系下異質對象集合的強大威力
- 缺點:
- 運行期綁定,導致一定程度的運行時開銷;
- 編譯器無法對虛函數進行優化
- 笨重的類繼承體系,對接口的修改影響整個類層次;
- 優點:
- 不同點:
- 本質不同,
早晚綁定
。靜態多態在編譯期決定,由模板具現完成,而動態多態在運行期決定,由繼承、虛函數實現; - 動態多態中接口是顯式的,以
函數簽名
為中心,多態通過虛函數在運行期實現,靜態多台中接口是隱式的,以有效表達式
為中心,多態通過模板具現在編譯期完成
- 本質不同,
- 相同點:
- 都能夠實現多態性,靜態多態/編譯期多態、動態多態/運行期多態;
- 都能夠使接口和實現相分離,一個是模板定義接口,類型參數定義實現,一個是基類虛函數定義接口,繼承類負責實現;
- 靜態多態
-