请看下面这段代码:

#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;
}
实现效果:


对于引用,也会出现类似的情况。

因此,为了避免出现类似例子一的表述不明的现象,我们一般不要重新在子类定义非虚函数。