原理
覆蓋函式,即在子類中用相同的函式名和簽名重寫父類的方法,虛函式,在子類中用相同的函式名和簽名重寫父類的方法(前面有virtual關鍵字)
特性
總結:調用函式的時候,關鍵看對象的類型 。
記住是對象的類型,不管是指針還是引用(同樣是對象的類型)。
好了有了對象的類型就好辦了。當你用這個對象(或者是指針、引用)去調用函式時,
1:該對象(實體)即不是指針或引用的形式,可以輕鬆的調用函式。
2:但是當我們用引用或指針形式時,有個問題是區別指針(引用)的類型和指針(引用)所指實體對象的類型。
A:你用指針來調用某函式,若函式是非虛函式,非虛函式是靜態編譯的(即編譯時刻確定的)。也就是說他不會去虛函式表找這個函式(因為不是虛函式),因 此調用的是指針類型的那個類的相關函式。即使派生類有這個函式(這是實際編程時的大忌!!!)。這就是 你的void FunctionA() const ;
B: 當你用這個指針去調用一個虛函式時,他就到虛函式表中,找這個名字的函式,從指針所指對象的類型(即派生類)依次向父類走,直到遇到第一個與次匹配的函式名。
實現
class Father
{
public:
void FunctionA() const
{
cout << "This is FunctionA of class Father." << endl;
}
virtual void FunctionB() const
{
cout << "This is FunctionB of class Father." << endl;
}
};
class Child : public Father
{
public:
void FunctionA() const
{
cout << "This is FunctionA of class Child." << endl;
}
virtual void FunctionB() const
{
cout << "This is FunctionB of class Child." << endl;
}
};
2。在將父類對象的指針指向子類對象的時候 Father* father = new Child;
如father->FunctionA(),則執行的是Father中的實現;father->FunctionB(),
則執行的是Child中的實現。
3。如果直接聲明子類對象,Child child;則無論child.FunctionA()還是 child.FunctionB(),執行的都是Child中的實現。
實現條件:
A.發生在不同的範圍(分別位於派生類和基類中);
B.函式名相同;
C.參數相同(個數相同、順序相同、類型相同);
D.基類的同名成員函式必須有關鍵字virtual修飾;