条款36:绝不重新定义继承而来的non-virtual函数

//绝不重新定义继承而来的non-virtual函数
#include <iostream>
using namespace std;

class B{
public:
	void mf()
	{cout << "调用基类B成员函数" << endl;}
	//......
};

class D:public B{
public:
	void mf(){cout << "this is D running" << endl;}
	//......
};

int main()
{
	D x;
	//***********************指针所展现的难以理解的行径***********************
	cout << "指针情况下:"<< endl;
	B *pb = &x;
	D *pd = &x;
	pb->mf();//pb虽然是指向派生类D的对象x,但是其所调用的函数却是 基类B
	         //(而非派生类D)的成员函数。输出结果为:“调用基类B成员函数”。

	pd->mf();//其所调用的函数却是 派生类D 的成员函数。输出结果为:“this is D running”
	x.mf();  //由于是D定义的对象,故调用 派生类D 的成员函数。输出结果为:“this is D running”

	//*****************Reference也会展现和指针一样难以理解的行径*****************
	cout << endl << "Reference情境:"<< endl;
	B &rb = x;
	D &rd = x;
	rb.mf();  //输出结果为:“调用基类B成员函数”
	rd.mf();  //输出结果为:“this is D running”


	return 0;
}

原因是:

non-virtual函数如 B::mf 和 D::mf 都是静态绑定,通过pb调用的non-virtual函数永远是B所定义的版本,及时pb指向一个类型为“基类B的派生类的对象”。

但virtual函数却是动态绑定的,所以它们不受这个问题之苦,即 mf() 若为虚函数,不论pb还是pd,均是调用D::mf() ,因为它们真正指的为D类型的对象

(Reference亦此)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值