《Effective C++》36:绝不重新定义继承而来的non-virtual函数

请看下面这段代码:

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


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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值