1. 程式人生 > 其它 >C++基礎(三)

C++基礎(三)

一、C++的三大特性

  封裝、繼承、多型

  多型意味著多種形態,當類之間存在層次結構,且不同類之間通過繼承關聯時,就會用到多型。  

  需要在基類中將公有函式名設定為虛擬函式,此時編譯器就會通過指標內容呼叫函式,而非通過指標型別呼叫函式(靜態多型)。

  1、多型

  普通函式的繼承是實現繼承,派生類繼承了基類函式,繼承的是函式的實現,虛擬函式的繼承是一種介面繼承,派生類繼承的是基類虛擬函式的介面,目的是為了重寫,達成多型。所以,如果不是為了實現多型,不要把函式定義成虛擬函式

  2、虛表與vptr指標

  當類中宣告虛擬函式的時候,編譯器會在類中生成一個函式虛表。虛擬函式表是一個儲存類成員函式指標的資料結構,這個虛擬函式表由編譯器自動生成和維護,virtual成員函式會被編譯器放入虛擬函式表中,存在虛擬函式時,每個物件中都有一個指向虛擬函式表的指標。

二、const的作用

  1、定義const常量,可以防止意外的修改

  2、相較於#define便於進行型別安全檢查

  3、相較於#define更節約記憶體空間

  4、編譯器不為普通const菜場裡那個分配儲存空間,使得沒有儲存和讀記憶體的操作,提高了效率。

三、解構函式

  是類的一種特殊的成員函式,會在每次刪除所建立的物件時執行,它不會返回任何值,也不會有任何引數。

  解構函式有助於在跳出程式前釋放資源。 

  基類的解構函式最好寫成虛基類,此時派生類的解構函式會自動重寫基類的解構函式,可以理解為編譯器對解構函式做了特殊處理。

四、行內函數(inline)

  目的是提高函式的執行效率,但是必需要和函式定義體放在一起,僅與函式宣告體放在一起沒有任何意義。

  缺點:濫用行內函數會讓程式變慢。

五、鑽石繼承問題(菱形繼承)

  

  問題描述:D類中會有兩份A類的成員(包括資料和方法),所以D的物件會包含A的兩個子物件,這會導致呼叫函式不明確(D的物件不清楚應該呼叫B中的函式還是C中的函式)。

 解決方法:class B : virtual public A{};

      class C : virtual public A{};

  即為B、C虛繼承A類後,類D中將會只有一個A的子物件。 

六、同名覆蓋問題

  場景描述:父類指標指向子類時,呼叫了一個在父類和子類中均存在的函式(在子類中把父類的此函式進行了重寫),此時呼叫的是哪個函式。

  1、父子間的賦值相容

  (1)子物件可以直接賦值/初始化父類物件。

  (2)父類指標可以直接指向子類物件。 

  (3)父類引用可以直接引用子類物件。

  2、父類指標(引用):當使用父類指標直接指向(引用)子物件時

  (1)子類退化為父類物件。

  (2)只能訪問父類中定義的成員

  (3)可以直接訪問被子類覆蓋的同名成員

  3、特殊的同名函式

  子類中可以重定義父類中已經存在的同名函式,這種重定義發生在繼承中,稱為函式重寫。

  若採用父類指標指向子類物件,並呼叫在子類中重寫過的函式,此時會呼叫父類物件中的函式為了解決此問題,引入多型的概念(通過虛繼承避免)。

七、引用

  引用就是某一變數(目標)的一個別名,對引用的操作和對變數直接操作完全一樣。

  引用的宣告方法:型別識別符號 &引用名=目標變數名。

  int a;

  int &ra =a;此時定義了一個引用ra,它是變數a的引用,也即別名。

  引用只是一個別名,本身不是資料型別,也不佔用儲存單元,系統也不分配儲存單元,對引用取地址等價於對目標變數取地址。

  無法建立對陣列的引用。

    1、常引用

    const型別識別符號 &引用名=目標變數名

    避免通過引用更改目標變數的值,達到了引用的安全性。

    2、引用作為返回值

    (1)、以引用返回函式值的時候,定義函式時需要在函式名前加&。

    (2)、用引用返回一個函式值的好處是,在記憶體中不產生被返回值的副本,可以節約記憶體開銷。