C++多態實現方式詳情
註:文章轉自公眾號:Coder梁(ID:Coder_LT)
在我們之前介紹的繼承的情況當中,派生類調用基類的方法都是不做任何改動的調用。
但有的時候會有一些特殊的情況,我們會希望同一個方法在不同的派生類當中的行為是不同的。舉個簡單的例子,比如speak
方法,在不同的類當中的實現肯定是不同的。如果是Human
類,就是正常的說話,如果是Dog
類可能是汪汪,而Cat類則是喵喵。
在這種情況下隻是簡單地使用繼承是無法滿足我們的要求的,最好能夠有一個機制可以讓方法有多種形態,不同的對象去調用的邏輯不同。這樣的行為稱為多態。
這裡稍微強調一下,多態是一種面向對象的設計思路,本身和C++不是強綁定的,其他語言當中一樣有多態,隻不過實現的方式可能有所不同。
在C++當中有兩種重要的機制用於實現多態:
- 在派生類當中重新定義基類的方法
- 使用虛方法
我們來看一個例子:
class Mammal { private: string name; public: Mammal(string n): name(n) {} string Name() const{ return name; } virtual void speak() const { cout << "can't say anything" << endl; } virtual ~Mammal() {}; }; class Human : public Mammal{ private: string job; public: Human(string n, string j): Mammal(n), job(j) {} virtual void speak() const { cout << "i'm human" << endl; } };
由於示例比較簡單,所以我們把類的聲明和實現寫在一起瞭。
從結構上來看,這就是一個簡單的繼承,我們實現瞭兩個類,一個叫做Mammal
,一個叫做Human
,然後給它們各自定義瞭一些成員變量。
值得註意的是speak
函數,我們在函數聲明前面加上瞭一個關鍵字virtual
,這表示這是一個虛函數。
方法被定義成虛方法之後,在程序執行的時候,將會根據派生類的類型來選擇執行的方法版本。在進行調用的時候,程序是根據對象類型而不是引用和指針的類型來選擇執行的方法,
如:
Mammal *m = new Human("man", "spiderman"); m->speak();
這裡我們用一個Mammal
的指針指向瞭一個Human
類型的對象,當我們調用方法的時候,由於speak
方法是一個虛方法。因此執行的時候程序會根據對象的類型也就是Human
去執行Human
對象中的speak
方法,而不是Mammal
中的。
通常我們會將析構函數也設置成虛方法,因為派生類當中往往有一些專屬成員,這是一種慣例。因為如果析構函數不是虛函數,那麼隻會調用對應指針類型的析構函數,這意味著可能在一些情況下產生錯誤和問題。
在上述的示例當中,我們是將類方法的實現和聲明寫在一起瞭,如果還是采取和之前一樣分開實現的方式,需要註意我們無需在函數簽名中加上virtual
關鍵字。
到此這篇關於C++多態實現方式詳情的文章就介紹到這瞭,更多相關C++多態內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 淺談Go語言多態的實現與interface使用
- c++ 虛繼承,多繼承相關總結
- C++數據結構繼承的概念與菱形繼承及虛擬繼承和組合
- 超級詳細講解C++中的多態
- C++實例分析講解臨時對象與右值引用的用法