多態性是容許你將父對象設置成爲和一個或更多的他的子對象相等的技術,賦值以後,父對象就能夠根據當前賦值給它的子對象的特性以不一樣的方式運做。簡單的說:容許將子類類型的指針賦值給父類類型的指針(一個接口,多種方法)。
C++ 支持兩種多態性:編譯時多態性,運行時多態性。
a、編譯時多態性(靜態多態):經過重載函數實現
b、運行時多態性(動態多態):經過虛函數實現。git
那麼多態的做用是什麼呢,封裝可使得代碼模塊化,繼承能夠擴展已存在的代碼,他們的目的都是爲了代碼重用。而多態的目的則是爲了接口重用。也就是說,不論傳遞過來的到底是那個類的對象,函數都可以經過同一個接口調用到適應各自對象的實現方法。github
運行時多態:ide
最多見的用法就是聲明基類的指針,利用該指針指向任意一個子類對象,調用相應的虛函數,能夠根據指向的子類的不一樣而實現不一樣的方法。若是沒有使用虛函數的話,則利用基類指針調用相應的函數的時候,將總被限制在基類函數自己,而沒法調用到子類中被重寫過的函數。由於沒有多態性,函數調用的地址將是必定的,而固定的地址將始終調用到同一個函數,這就沒法實現一個接口,多種方法的目的了。模塊化
非運行時多態:函數
經過函數重載實現spa
簡而言之:指針
隱藏是指派生類的函數屏蔽了與其同名的基類函數,規則以下:code
虛函數: 就是容許被其子類從新定義的成員函數,子類從新定義父類虛函數的作法,可實現成員函數的動態覆蓋(Override)。對象
純虛函數: 是在基類中聲明的虛函數,它在基類中沒有定義,但要求任何派生類都要定義本身的實現方法。在基類中實現純虛函數的方法是在函數原型後加「=0」
virtual void funtion()=0
抽象類: 包含純虛函數的類稱爲抽象類。因爲抽象類包含了沒有定義的純虛函數,因此不能進行實例化。
純虛函數的做用:
virtual ReturnType Function()= 0;
),則編譯器要求在派生類中必須予以重寫以實現多態性。同時含有純虛擬函數的類稱爲抽象類,它不能生成對象。這樣就很好地解決了上述兩個問題。示例代碼:
#include<iostream> using namespace std; //基類對象 class Base { public: //有virtual關鍵字,運行時多態 virtual void f(float x) { cout<<"Base::f(float)"<< x <<endl; } //無viratul關鍵字,不會發生運行時多態 void g(float x) { cout<<"Base::g(float)"<< x <<endl; } void h(float x) { cout<<"Base::h(float)"<< x <<endl; } }; class Derived : public Base { public: virtual void f(float x) { cout<<"Derived::f(float)"<< x <<endl; //多態、覆蓋 } //子類與父類的函數同名,無virtual關鍵字,則爲隱藏 void g(int x) { cout<<"Derived::g(int)"<< x <<endl; //隱藏 } void h(float x) { cout<<"Derived::h(float)"<< x <<endl; //隱藏 } }; int main(void) { Derived d; //子類 Base *pb = &d; //基類指針指向子類 Derived *pd = &d; //子類指針指向本身 // Good : behavior depends solely on type of the object pb->f(3.14f); // Derived::f(float) 3.14 調用子類,多態 pd->f(3.14f); // Derived::f(float) 3.14 調用子類 // Bad : behavior depends on type of the pointer pb->g(3.14f); // Base::g(float) 3.14 無多態,調用本身的 pd->g(3.14f); // Derived::g(int) 3 無多態,調用本身的 // Bad : behavior depends on type of the pointer pb->h(3.14f); // Base::h(float) 3.14 無多態,調用本身的 pd->h(3.14f); // Derived::h(float) 3.14 無多態,調用本身的 return 0; }