多型分為兩類
1.靜態多型:函式過載和運算子過載屬於靜態多型,復用函式名
2.動態多型:派生類和虛函式實現執行時多型
首先讓我們看這段**:
#include
using
namespace std;
class
animal};
class
cat:
public animal };
void
dospeak
(animal &animal)
void
test01()
intmain()
結果為:動物在說話
我們想要的是貓在說話,可最後輸出的結果卻是動物在說話,為什麼呢?
因為dospeak函式位址早繫結了,在編譯階段就確定了函式位址
那麼我們要怎樣做才能讓貓說話呢?
非常簡單,就是利用動態多型,就是要讓dospeak函式的位址晚繫結(在執行階段進行繫結),我們只要在父類的同名speak函式前面加virtual關鍵字,現在speak函式就變成了虛函式,就解決了上述問題。
**如下:
#include
using
namespace std;
class
animal};
class
cat:
public animal };
void
dospeak
(animal &animal)
void
test01()
intmain()
結果為:貓在說話
重寫的概念:
1.函式的返回型別相同
2.函式名相同
3.引數列表相同
動態多型的滿足條件:
1.有繼承關係
2.子類要重寫父類的虛函式
動態多型的使用:
父類的指標或引用指向子類的物件
現在我們來看看多型的原理,首先我們看一下下面這段**:
#include
using
namespace std;
class
animal};
class
cat:
public animal };
void
dospeak
(animal &animal)
void
test01()
intmain()
結果為size of animal = 1
現在我們在animal的speak函式前面加上virtual,寫成多型的形式,結果又是多少呢?
#include
using
namespace std;
class
animal};
class
cat:
public animal };
void
dospeak
(animal &animal)
void
test01()
intmain()
結果為:size of animal = 4
這說明,加了virtual後,這個類的內部結構發生了改變。
那到底多了什麼東西,導致這個類變成了4個位元組呢?
結果:多了指標。
現在讓我們看看這其中發生的變化,
首先我們要知道:
vfptr - 虛函式(表)指標
v - virtual
f - function
ptr - pointer
vftable - 虛函式表
v - virtual
f - function
table - table
現在讓我們看看animal類內部結構:
cat內部結構:
當父類中的指標或者引用指向子類物件的時候,就發生了多型。
我們就相當於寫了這樣一段**:
animal &animal = cat;
animal,speak();
當我們呼叫animal的speak函式時,由於指向的是cat物件,所以編譯器會從cat的虛函式表中找speak函式,就相當於在執行階段發生了多型。
原理:由於我們寫了乙個虛函式,類的內部發生了結構的改變,多了乙個虛函式表指標,指向虛函式表,虛函式表內部寫的是虛函式的函式入口位址,當子類重寫了虛函式表,會把自身的虛函式表給替換掉,這裡的替換就是cat類中發生的替換。
多型的原理剖析
多型滿足條件 多型分為兩類 靜態多型 函式過載 和 運算子過載屬於靜態多型,復用函式名。動態多型 派生類和虛函式實現執行時多型。靜態多型和動態多型區別 靜態多型的函式位址早繫結 編譯階段確定函式位址。動態多型的函式位址晚繫結 執行階段確定函式位址。建立乙個父類 class animal 當不加vir...
剖析C 的多型
一 什麼是多型 物件導向程式設計中的另外乙個重要概念是多型性。在執行時,可以通過指向基類的指標,來呼叫實現派生類中的方法。可以把一組物件放到乙個陣列中,然後呼叫它們的方法,在這種場合下,多型性作用就體現出來了,這些物件不必是相同型別的物件。當然,如果它們都繼承自某個類,你可以把這些派生類,都放到乙個...
剖析C 的多型
一 什麼是多型 物件導向程式設計中的另外乙個重要概念是多型性。在執行時,可以通過指向基類的指標,來呼叫實現派生類中的方法。可以把一組物件放到乙個陣列中,然後呼叫它們的方法,在這種場合下,多型性作用就體現出來了,這些物件不必是相同型別的物件。當然,如果它們都繼承自某個類,你可以把這些派生類,都放到乙個...