关于动态多态的错题分析

C++中关于动态多态分析,对于多次在基类和派生类中来回调用的一些情况,仍然会产生动态多态的情况。
求如下程序的输出结果:

#include<iostream>
#include<string>
using namespace std;

class Base
{
public:
	virtual void Send()
	{ 
		cout << "\nSend_Base:" << mVal << endl;
	}
	~Base() {}
	void OutPut()
	{
		Send();
	}

	int mVal;
};

class Derive :public Base
{
public:
	Derive() { mVal = 100; }
	virtual void Send()
	{
		mVal++;
		cout << "\nSend_Der: " << mVal << endl;
	}
	void OutPut()
	{
		Base::OutPut();
	}
};

int main()
{
	Derive user;
	Base &base = user;
	base.Send();
	
	Base *p = &base;
	p->OutPut();
	
	user.OutPut();
	return 0;

}

1、分析

(1)、Send() 为虚函数,当通过基类的引用或指针来调用该虚函数时会产生动态多态。所以Base &base=user 为基类的引用绑定到派生类的对象上,base.Send()中由于调用的为虚函数,所以会产生动态多态,此时基类引用绑定的是派生类对象,所以会调用派生类的虚函数。
(2)、第二个输出有很大的迷惑性,由于base是绑定到派生类对象上的引用,所以base相当于派生类对象的别名。Base *p=&base 相当于将派生类对象的地址赋给基类指针,p就成为指向派生类对象的基类指针,此时若调用虚函数就会产生动态多态的行为。而迷惑在于p->OutPut(),在类中OutPut()为普通成员函数,而非虚函数。因此就会调用基类的OutPut函数,但是基类OutPut()函数中又调用了虚函数Send(),而此时的调用对象为指向派生类的基类指针,因此仍然会产生动态多态的行为,会调用派生类的虚函数Send()
(3)、第三个是直接使用派生类对象来调用OutPut()函数,所以会直接调用派生类的OutPut成员函数,但是该成员函数又直接调用了基类的OutPut函数,因此会回到基类的OutPut函数中去调用虚函数Send,此时由于调用对象一直是派生类,所以会直接调用派生类所对应的虚函数。在此处是拐了好几个弯的来回在基类和派生类中进行调用,但是由于是直接通过派生类对象来进行调用的,而不是基类指针或引用来调用,所以在第三个调用中不会产生动态多态。

总结分析:在涉及到虚函数的调用中,有可能会产生动态多态的情况下,首先看是否通过基类的指针或引用来最终调用了虚函数(不管拐了多少弯,最后调用虚函数的时候一定要看,调用的对象是否为基类指针或引用)。若为基类指针或引用就会产生多态行为,否则就只是根据调用函数的对象类型来确定调用的版本。

2、调用结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值