1. 爲什麼要使用虛函數?
- 在C++語言中,基類將類型相關的函數與派生類不做改變直接繼承的函數區分對待,對於某些函數,基類希望它的派生類各自定義適合自身的版本,此時基類就將這些函數聲明成虛函數。
- 虛函數使用virtual關鍵字表示,如下面程序中Parent類中的Function2就是虛函數
- 基類中定義的虛函數必須在其派生類中有和其完全相同的函數聲明(函數名、參數列表,返回值),使用override關鍵字,表示該函數可能會覆蓋基類中對應的虛函數。
2. 看一個例子
#include <iostream>
using namespace std;
class Parent
{
public:
char data[20];
void Function1(){
printf("This is parent,function1\n");
}
virtual void Function2() {
printf("This is parent,function2\n");
}
}parent;
class Child:public Parent
{
void Function1(){
printf("This is child,function1\n");
}
void Function2() override{
printf("This is child,function2\n");
}
}child;
int main(int argc, char* argv[])
{
int a;
Parent *p;
scanf("%d",&a);
if(a)
p=&child;
else
p=&parent;
p->Function1();
p->Function2();
return 0;
}
1
This is parent,function1
This is child,function2
0
This is parent,function1
This is parent,function2
一句概括的話:當使用基類的指針或引用調用虛函數時,會發生動態綁定,即該指針或引用可能綁定一個基類對象,也可能綁定一個派生類對象,這在函數運行的時候才能得知。如果綁定的是基類對象,則調用的是基類中的虛函數,如果綁定的是派生類對象,則調用的是派生類中的虛函數。
3. 動態綁定和靜態綁定的概念
- 靜態綁定:對於引用或指針,在編譯過程中就已經綁定了對象;
- 動態綁定:對於引用或指針,在編譯過程中不知道該綁定什麼對象,只有在運行時才進行綁定;
注意:當且僅當基類的指針或引用調用虛函數時,纔會發生動態綁定
- 因此,上面主程序中
p->Function1();
調用Function1時,由於Function1不是虛函數,因此不會發生動態綁定。在編譯時,p就已經綁定了其聲明的對象Parent類,因此其調用的自然是Parent中的Function1;
p->Function2();
調用Function2時,由於Function2是虛函數,因此發生動態綁定。編譯時,p不會綁定任何對象,在運行時,如果p綁定了Parent對象,則調用的是Parent類中的虛函數,如果綁定了Child對象,則調用的是Child類中的虛函數;
-