1.多態的基本概念
多態分爲兩類:
- 靜態多態:函數重載和運算符重載屬於靜態多態,複用函數名
- 多態多態:派生類以及虛函數實現運行時多態
靜態多態和動態多態的區別:
- 靜態多態的函數地址早綁定,編譯階段確定函數地址
- 動態多態的函數地址晚綁定,運行階段確定函數地址
#include <iostream>
using namespace std;
class animal
{
public:
//虛函數
virtual void speak()
{
cout << "animal is speaking" << endl;
}
};
class cat :public animal
{
public:
void speak()
{
cout << "cat is speaking" << endl;
}
};
//地址早綁定,在編譯階段確定了函數地址
//如果想讓貓說話,就要讓函數地址在運行的時候綁定
void dospeak(animal &animal)
{
animal.speak();
}
void test1()
{
cat cat;
dospeak(cat); // animal &animal = cat 允許父子之間不進行強制類型轉換
}
int main()
{
test1();
return 0;
}
動態多態的滿足條件:
- 有繼承關係
- 子類要重寫父類的虛函數 (重寫:函數返回值,函數名稱,函數參數列表都相等)
動態多態的使用:
- 父類的引用或者指針執行子類對象
2.多態的原理分析
當animal中有虛函數,會產生一個虛函數指針,指向虛函數表,表中記錄虛函數的地址。當cat繼承自animal時,把animal中的虛函數指針以及虛函數表都繼承了過來,此時cat內部沒有重寫speak函數,所以虛函數表不變。
當子類重寫父類的虛函數之後,子類的虛函數表內部會被替換成子類的虛函數地址。
所以當父類的指針或者引用指向虛函數表的時候,會指向具體子類的虛函數表,此時就會發生多態