多態總結
一、什麼是多態?
多態就是具有多種形式或形態的情形。在我C++中就是有幾個相似卻不完全相同的對象,對這些對象發出同一消息時,這些對象分別執行不同的操作,完成不同的功能。
二、多態的分類
三、靜態多態
1.函數重載
(1)定義
函數重載是指在同一作用域內,可以有一組具有相同函數名,不同參數列表的函數,這組函數被稱爲重載函數。
(2)注意
重載函數的參數個數,參數類型,參數順序三者中必須至少有一個不同。函數返回值可以相同也可以不同。
(3)程序實例
#include<iostream>
using namespace std;
int Add(int left, int right)
{
return left + right;
}
float Add(float left, float right)
{
return left + right;
}
int main()
{
cout << Add(10, 20) << endl;
cout << Add(12.34f, 56.78f) << endl;
system("pause");
return 0;
}
通過實例可以發現,函數重載是怎麼調用對應函數的呢!通過函數調用,獲取函數名,找到同名函數,然後獲得函數各參數表達式類型,同時與實參比較是否匹配,如果匹配則調用該函數,如果沒有匹配類型則報錯。
四、動態多態
1.虛函數
(1)定義
使用virtual關鍵字修飾的函數稱爲虛函數。
(2)注意
一個類函數的調用並不是在編譯時刻被確定,而是在運行時刻被確定。
(3)程序實例
#include<iostream>
using namespace std;
class CBase
{
public:
virtual void FunTest1(int _iTest)
{
cout << "CBase::FunTest1()" << endl;
}
void FunTest2(int _iTest)
{
cout << "CBase::FunTest2()" << endl;
}
virtual void FunTest3(int _iTest1)
{
cout << "CBase::FunTest3()" << endl;
}
virtual void FunTest4(int _iTest)
{
cout << "CBase::FunTest4()" << endl;
}
};
class CDerived :public CBase
{
public:
virtual void FunTest1(int _iTest)
{
cout << "CDerived::FunTest1()" << endl;
}
virtual void FunTest2(int _iTest)
{
cout << "CDerived::FunTest2()" << endl;
}
void FunTest3(int _iTest1)
{
cout << "CDerived::FunTest3()" << endl;
}
virtual void FunTest4(int _iTest1, int _iTest2)
{
cout << "CDerived::FunTest4()" << endl;
}
};
int main()
{
CBase* pBase = new CDerived;
pBase->FunTest1(0);
pBase->FunTest2(0);
pBase->FunTest3(0);
pBase->FunTest4(0);
CDerived d;
d.FunTest4(0, 0);
d.CBase::FunTest4(0);
system("pause");
return 0;
}
(4)總結
1.派生類重寫基類的虛函數實現多態,要求函數名、參數列表、返回值完全相同。(協變除外)
2、基類中定義了虛函數,在派生類中該函數始終保持虛函數的特性。
3、只有類的成員函數才能定義爲虛函數,靜態成員函數不能定義爲虛函數。
4、如果在類外定義虛函數,只能在聲明函數時加virtual關鍵字,定義時不用加。
5、構造函數不能定義爲虛函數,雖然可以將operator=定義爲虛函數,但最好不要這麼做,使用時容易混淆。
6、不要在構造函數和析構函數中調用虛函數,在構造函數和析構函數中,對象是不完整的,可能會出現未定義的行爲。
7、最好將基類的析構函數聲明爲虛函數。(析構函數比較特殊,因爲派生類的析構函數跟基類的析構函數名稱不一樣,但是構成覆蓋,這裏編譯器做了特殊處理)
8、虛表是所有類對象實例共用的。