C++中類的多態性通過虛函數來實現
虛函數與純虛函數
虛函數
定義方法
:在基類的函數前面加上virtual關鍵字
定義某個函數爲虛函數是爲了能夠使用基類指針來調用派生類函數
#include <iostream>
using namespace std;
class A
{
public:
void print1()
{
cout << 1 << endl;
}
virtual void print2()
{
cout << 2 << endl;
}
};
class B : public A
{
public:
void print1()
{
cout << 3 << endl;
}
void print2()
{
cout << 4 << endl;
}
};
int main()
{
A a;
B b;
A *p;
p = &a;
p->print1();
p->print2();
p = &b; //基類指針指向派生類對象
p->print1();
p->print2();
return 0;
}
上面代碼輸出 1 2 1 4
,前兩個很清楚,基類指針指向基類對象,調用的都是基類本身函數,自然輸出1 2
。
後面兩個輸出 1 4
,體現了類的多態性,輸出1
是因爲基類指針指向派生類對象,只會調用基類的函數(也即靜態綁定),輸出2
的原因是因爲基類中的print2()是虛函數,由於每個虛函數都有一個虛函數列表,此時p調用print1()並不是直接調用函數,而是通過虛函數列表找到相應的函數的地址,因此根據指向的對象不同,函數地址也將不同,這裏將找到對應的子類的print1()函數的地址(也即動態綁定)。
純虛函數
定義方法:在虛函數後面加上=0
性質:
- 包含純虛函數的類稱爲抽象類,抽象類不可以創建對象。
- 純虛函數在基類中沒有定義,但是在派生類必須找到相應的實現方法,否則派生類也爲抽象類。
#include <iostream>
using namespace std;
class A
{
public:
void print1()
{
cout << 1 << endl;
}
virtual void print2() = 0; //定義了一個純虛函數
};
class B : public A
{
public:
void print1()
{
cout << 3 << endl;
}
void print2()
{
cout << 4 << endl;
}
};
int main()
{
// A a; //錯誤 A爲抽象類
B b;
A *p;
p = &b; //基類指針指向派生類對象
p->print1();
p->print2();
return 0;
}