C++ 虛函數是類的一個成員,再衍生類別中,它的功能可以被重寫(over-ridden),在衍生類別中的一組新實現能夠替代整個函數。
虛函數不同於函數重載(overloading)
- 虛函數是類的成員
- 用 virtual關鍵字 聲明
- 一般會在衍生類別中有一個不同的功能。
- 函數調用在運行時解析
1.非虛函數是在編譯時間就解析了,這種機制叫靜態繫結。
2.而虛函數是在運行時解析,這種機制叫動態綁定。
3.非虛函數是你不得不做並且你必須按照這個方式做
4.虛函數是你必須做,但是你不必按照這個方式做
- 引入虛函數的原因:
最重要的原因是要在衍生類別中實現不同的功能。
假設一個基類叫Window,包含一個虛函數叫Create ,衍生類別叫 CommandButton,
裡面有對Create的覆寫。
class Window // Base class for C++ virtual function example
{
public:
virtual void Create() // virtual function for C++ virtual function example
{
cout <<"Base class Window"<<endl;
}
};
class CommandButton : public Window
{
public:
void Create()
{
cout<<"Derived class Command Button - Overridden C++ virtual function"<<endl;
}
};
void main()
{
Window *x, *y;
x = new Window();
x->Create();
y = new CommandButton();
y->Create();
}
輸出是:
Base class Window
Derived class Command Button
如果這個函數沒有被聲明為虛函數,那麼在所有的時間裡基類函數都會被調用,函數的地址
會在編譯期間靜態綁定,但是現在,因為函數被聲明為虛函數,這個函數就會在運行時被
連結並且提交衍生類別函數
為什麼預設情況下不是虛函數而是非虛函數?
因為這樣效率更高,它不是動態綁定,也不需要為函數產生Vtable 和 VPointer.
這樣就使你的應用程式資料空間更小。
虛函數機制:
只要一個程式聲明了虛函數,系統就會為這個類產生一個 V-table(virtual table)。這個
表包含指向類虛函數的地址和衍生類別每一個對象得函數指標。只要
對虛函數有調用,V-Table 就會解析函數地址,這就是在虛函數調用時
動態綁定的實質。