什麼是多態?
編程
多態按照字面的意思就是「多種狀態 」的意思。在C++中多態有着更普遍的含義。下面着重介紹C++語言中關於多態的一些知識點。ide
C++中多態分爲靜態多態和動態多態。靜態多態經過函數重載和泛型編程實現。動態多態經過虛函數來實現。參照下圖:函數
靜態多態:spa
編譯器在編譯期間完成的,編譯器根據函數實參的類型(可能會進行隱式類型轉換),可推斷出要調用那個函數,若是有對應的函數就調用該函數,不然出現編譯錯誤。3d
int Add(int a1, int a2) { return a1 + a2; } double Add(double d1, double d2) { return d1 + d2; } int main() { cout << Add(10, 20) << endl;//調用第一個函數 cout << Add(12.3, 34.5) << endl;//調用第二個函數 return 0; }
以上例子是經過函數重載實現靜態多態的。指針
4. 動態多態:對象
動態綁定:在程序執行期間(非編譯期)判斷所引用對象的實際類型,根據其實際類型調用相應的方 法。blog
使用virtual關鍵字修飾函數時,指明該函數爲虛函數,派生類須要從新實現,編譯器將實現動態綁定。 接口
class Base { public: virtual void FunTest1()//虛函數 { cout << "Base::FunTest1()" << endl; } virtual void FunTest2()//虛函數 { cout << "Base::FunTest2()" << endl; } }; class Derived:public Base { public: void FunTest1()//對基類的基類虛函數FunTest1()進行重寫 { cout << "Derived::FunTest1()" << endl; } void FunTest3() { cout << "Derived::FunTest3()" << endl; } void FunTest4() { cout << "Derived::FunTest4()" << endl; } }; int main() { Base b; Derived d; b.FunTest1(); b.FunTest2(); d.FunTest1();//對基類函數進行了重寫,調用派生類的函數 d.FunTest2();//未對基類函數進行重寫,調用基類函數 d.FunTest3(); d.FunTest4(); Base *pb = &b; pb->FunTest1(); pb = &d; pb->FunTest1(); return 0; }
以上代碼運行結果以下:ci
由運行結果可知:
(1).若是在派生類中對基類函數進行了重寫,則在派生類中就調用派生類的成員函數。不然將調用基類的成員函數。
(2).動態綁定條件:
a.必須是虛函數
b.經過基類類型的引用或者指針調用
5.純虛函數
在成員函數的形參後面寫上=0,則成員函數爲純虛函數。包含純虛函數的類叫作抽象類(也叫接口類),抽象類不能實例化出對象。純虛函數在派生類中從新定義之後,派生類才能實例化出對象。
純虛函數舉例:
class A { virtual void Test() = 0;//純虛函數 };
6.總結:
(1).派生類重寫基類的虛函數實現多態,要求函數名、參數列表、返回值徹底相同。
(2).基類中定義了虛函數,在派生類中該函數始終保持虛函數的特性。
(3).只有類的成員函數才能定義爲虛函數,靜態成員函數不能定義爲虛函數。
(4).若是在類外定義虛函數,只能在聲明函數時加virtual關鍵字,定義時不用加。
(5).構造函數不能定義爲虛函數
(6).不要在構造函數和析構函數中調用虛函數,在構造函數和析構函數中,對象是不完整的,可能會出現未定義的行爲。
(7).虛表是全部類對象實例共用的。