一.C++實現多態的條件
1.派生類對象必須賦值給基類的引用或者指向基類的指針。
2.派生類的繼承方式必須是公有繼承public。
如果是protected繼承或者是private繼承,那麼子類的所有方法只能在內部訪問,這時候就不需要多態了。一般會有語法報錯。
3.基類中的同名函數必須定義爲虛函數。
舉個例子:
#include<iostream>
using namespace std;
int main()
{
class B { public: virtual void f() { cout << "我是B" << endl; }; };
class P :public B { public:void f() { cout << "我是P" << endl; } };
class Q :public B { public:void f() { cout << "我是Q" << endl; } };
P p;
Q q;
B b1 = p; //這種情況只能是調用父類的函數
b1.f();
B& b2= p;
b2.f();
B& b3 = q;
b3.f();
}
運行結果:
二.關於虛函數使用的幾點注意規則
1.必須首先在基類中聲明虛函數。在多繼承的情況下,也可以不在最高層的基類中聲明虛函數。
例如在第二層定義的虛函數,可以和第三層的虛函數形成動態聯編,但是,一般都是在最高層的基類中首先聲明虛函數。
2.基類和派生類的同名函數,函數名,返回值,參數表必須全部相同,才能作爲虛函數來使用。
否則即使用virtucal來說明,也不具有虛函數的行爲。
3.虛函數不可以是靜態成員函數,構造函數也不可以是虛函數。
因爲虛函數的調用需要虛表,虛表又由構造函數建立。
4.析構函數可以聲明爲虛函數,可以定義虛析構函數。
5.在多繼承中,最高層和第三層有兩個原型相同的函數,並且在最高層聲明爲虛函數,則第三層的這個函數也是虛函數。
這種關係並不會因爲第二層沒有定義這個函數而受影響。
三.補充幾點虛函數和純虛函數
1.虛函數是爲了實現多態服務的。
有虛函數的類,可以被實例化,但是虛函數必須實現(有函數體,裏面有什麼不要緊)這個很好理解,類中的函數沒有實現編譯時候會報錯。
2.純虛函數是爲了抽象類服務的。而抽象類作用是爲了靈活規範子類以及多態。
有純虛函數的類無法實例化,即抽象類無法被實例化。
純虛函數必須在子類當中被實現,否則該子類也只能是抽象類。
附上幾道試題:
https://www.nowcoder.com/questionTerminal/81c3e33a2f834b168487c22e85a85b0f
https://www.nowcoder.com/questionTerminal/a6d17dac54c64d4f8712c578ef5d2dc3?toCommentId=1240609