请看下面这段代码:
#include <iostream>
using namespace std;
class Base
{
public:
void Show()
{
cout << "I'm Base::Show()." << endl;
}
};
class Derive : public Base
{
public:
//遮盖了 Base::Show();
void Show()
{
cout << "I'm Derive::Show()." << endl;
}
};
int main()
{
Derive* pD = new Derive();
pD->Show(); //调用Derive::Show();
Base* pB = new Derive();
pB->Show(); //调用Base::Show();
return 0;
}
实现效果:
但是,这就让我们产生疑问了,pB指针明明指向的就是Derive对象,为什么会调用 Base::Show() 呢?
这是因为非虚函数Base::Show()和Derive::Show()都是静态绑定(statically bound)的。静态绑定是指在程序编译过程中,把函数(方法或者过程)调用与响应调用所需的代码结合的过程称之为静态绑定。这就意味着,由于pB被声明为指向Base类的指针,所以通过pB指针调用的所有的非虚函数永远是Base类所定义的版本。即使pB指向一个类型为Base的派生类的对象。
与此对应,virtual函数是动态绑定(dynamically bound)的。因此就不会有上面的问题。
如:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void Show()
{
cout << "I'm Base::Show()." << endl;
}
};
class Derive : public Base
{
public:
//重写了 Base::Show();
virtual void Show()
{
cout << "I'm Derive::Show()." << endl;
}
};
int main()
{
Derive* pD = new Derive();
pD->Show(); //调用Derive::Show();
Base* pB = new Derive();
pB->Show(); //调用Derive::Show();
return 0;
}
实现效果:
对于引用,也会出现类似的情况。
因此,为了避免出现类似例子一的表述不明的现象,我们一般不要重新在子类定义非虚函数。