类继承中的缺省参数值

写这篇是因为发现了类继承中一个有趣的现象。我们都知道,C++类中的virtual函数是动态绑定的,那么virtual函数的缺省参数呢?

想必大家对动态绑定和静态绑定都不陌生了吧?简单来说,动态绑定就是运行期决定执行的函数(或行为),静态绑定则是编译期确定的,或者声明时确定的。

virtual函数是动态绑定的,而缺省参数却是静态绑定。为了说明这个问题,先看一个再简单不过的例子:

#include <iostream>

using namespace std;

class Base
{
public:
	virtual void print_num(int x = 5)
	{
		cout << "This is class Base!" << endl;
		cout << "x = " << x << endl;
	}
};

class Derived_1 : public Base
{
public:
	virtual void print_num(int x = 10)
	{
		cout << "This is class Derived_1!" << endl;
		cout << "x = " << x << endl;
	}
};

class Derived_2 : public Base
{
public:
	virtual void print_num(float x = 3.14159)
	{
		cout << "This is class Derived_2!" << endl;
		cout << "x = " << x << endl;
	}
};

int main()
{
	Base *p1 = new Derived_1;
	Base *p2 = new Derived_2;
	Derived_1 p3;
	Derived_2 p4;
	
	p1->print_num();
	p2->print_num();
	p3.print_num();
	p4.print_num();
	
	delete p1;
	delete p2;
	
	return 0;
}

定义一个基类Base,声明一个virtual函数print_num,缺省参数值为5;定义两个Base的派生类,分别定义virtual函数print_num,缺省参数为整数10和浮点数3.14159。根据经验,我们都知道,在执行成员函数时,会根据指针所指对象类型执行相应类型下的函数,p1指向的动态类型为Derived_1,p2指向的动态类型为Derived_2,因此,p1->print_num()应执行的是Derived_1类中的print_num(),p2->print_num()应该执行的是Derived_2中的print_num()。实际是否这样呢?让我们来看一下执行结果:

有点意外是不是?

p3和p4的输出结果在意料之内。那么怎样解释p1和p2的输出结果?

p1的静态类型为Base,动态类型为Derived_1,那么在运行期执行p1->print_num()时,会自动调用Derived_1的同名函数print_num(),但由于缺省参数为静态绑定,因此,传入的缺省参数为整数5,因此p1->print_num()的输出是合理的。

p2的静态类型为Base,动态类型为Derived_2,运行期间貌似应该执行Derived_2得print_num(),但由于输入参数为静态绑定,即为int型的数值5,而Derived_2中没有对print_num(int)的定义,因此实际执行的还是基类的print_num()函数。

那么问题来了,如果让p2打印一个float类型的数值,结果会是怎样?结果很可能仍然出乎我们的意料,我们在上面的程序里再添加几行:

int main()
{
	Base *p1 = new Derived_1;
	Base *p2 = new Derived_2;
	Derived_1 p3;
	Derived_2 p4;
	
	p1->print_num();
	p2->print_num();
	
	/* 新增的测试 */
	p1->print_num(50);
	p2->print_num(100);
	float f = 8.234;
	p2->print_num(f);
	
	p3.print_num();
	p4.print_num();
	
	delete p1;
	delete p2;
	
	return 0;
}

p2->print_num(f)并没有如我们预期打印出float数值,而是仍然调用了Base中的print_num(),并对传进去的float参数做取整输出。这大概是最反直觉的结果了吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值