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();
}
{
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 就会解析函数地址,这就是在虚函数调用时
动态绑定的实质。