C++之封裝繼承和多態

C++中很是重要的概念,尤爲是相對於C語言而言,也是其具備如此高的工程使用性的重要緣由。編程

封裝安全

所謂封裝是將某些東西隱藏起來,讓外界沒法直接使用,而必須經過某些特定的方式才能訪問。也便是,將抽象獲得的數據和行爲(相似於屬性和方法)結合構成一個有機總體,將數據與操做數據的函數構成類,其中數據和函數都是類的成員。函數

其目的是將對象的使用者和設計者隔離開來,提升軟件的可維護性和可修改性,使用者沒必要了解具體的實現細節而只是經過外部接口及特定的訪問權限使用類成員,從而加強了安全性且簡化了編程,也使得不一樣類之間的相互影響降到最低。優化

一個類的成員有三種訪問權限能夠選擇spa

  • public        全部人都可訪問
  • private    只有當前類中成員函數能夠訪問
  • protected  只有當前類中和當前類的派生類中的成員函數能夠訪問

若是沒有顯示聲明,class中的成員數據或成員函數默認訪問權限是private,struct中默認訪問權限是public設計

繼承指針

指的是新類從已有的類中獲得已有的特性。調試

繼承使得子類具備父類的某些數據和函數,而不須要再次編寫相同的代碼,在繼承的同時,子類也能夠從新定義某些數據和函數並覆蓋父類原有的數據和函數。code

與類的成員訪問權限相關,繼承方式也分爲三種:public,private,protected對象

通常分爲單一繼承和多重繼承,經常使用的是單一繼承,編程簡單,可讀性好。

須要注意的是class默認是private繼承,而struct默認是public繼承。

父類中的訪問權限 繼承方式 子類中的訪問權限
public public public
private No access
protected protected
public private private
private No access
protected private
public protected protected
private No access
protected protected

子類會繼承父類/基類除構造函數和析構函數之外的成員函數,通常析構函數定義爲虛函數,不然的話析構時只會調用父類/基類中定義的析構函數而不會調用子類/派生類中的析構函數。

多態

父類成員函數前加virtual修飾就變成了虛函數。

純虛函數就是父類只定義了虛函數而沒有實現,則必須在子類中實現。若是子類中沒有實現則子類仍爲虛類,須要子類的子類去實現純虛函數,即哪一層子類實現了純虛函數,哪一層的子類才能夠被初始化。純虛函數至關於一個接口,子類必須實現這個接口才可使用。

而多態性就是爲了接口重用,不管傳遞過來的是哪一個子類的對象,都能調用相應的子類函數。

多態是咱們能夠用相同的方式處理不一樣類型的對象,極大地提升了代碼的可重複性。

多態性容許將子類類型的指針賦值給父類類型的指針,常經過虛函數來實現。虛函數就是容許子類從新定義的成員函數。

子類重寫父類中的虛函數時,即便不用virtual聲明,該函數也是虛函數,而父類中必需要有virtual聲明。

一個接口,多種方法,多態主要有兩種形式。

靜態多態

在編譯期將函數連接起來,此時便可肯定調用哪一個函數或模板,靜態多態經過重載和模板實現。

在宏多態中,經過定義變量,編譯時直接把變量替換,實現宏多態。

  • 優勢
  1. 泛型編程,STL,很是便利
  2. 編譯期完成,提升了運行效率
  3. 具備很強的適配性和鬆耦合性
  • 缺點
  1. 使得編程可讀性下降,代碼調試困難
  2. 沒法實現木板的分離編譯,工程量大時編譯時間較長
  3. 沒法處理異質對象集合

動態多態

在程序運行期間才能肯定調用哪一個函數或實現。父類指針或引用可以指向子類對象,調用子類的函數,因此在編譯時沒法肯定調用哪一個函數。

例如在父類中寫一個虛函數,子類中進行重寫,用一個指向父類的指針調用虛函數,實際上會調用在子類中重寫的虛函數。

運行期多態的實現依賴於虛函數機制,當某個類聲明瞭虛函數時,編譯器將爲該類對象安插一個虛函數表指針,併爲該類設置一個惟一的虛函數表,表中存放該類虛函數的入口地址,運行期間經過虛函數表指針與虛函數表去肯定該類虛函數的真正實現。

  • 優勢
  1. 面向對象設計中很是重要的特性,對客觀世界直覺的認識。
  2. 能夠處理同一繼承體系下的異質類集合
    vector<Animal*> anims;
    Animal *anim1 = new Dog;
    Animal *anim2 = new Cat;
    
    // 處理異質類集合實例
    anims.push_back(anim1);
    anims.push_back(anim2);
  • 缺點
  1. 運行期間進行虛函數綁定,增長了程序運行開銷
  2. 龐大的類繼承層次,對接口的修改容易影響類的繼承層次
  3. 虛函數在運行期綁定,編譯器沒法對其進行優化
相關文章
相關標籤/搜索