理论教育 面向对象程序设计中的重载函数用法及匹配原则

面向对象程序设计中的重载函数用法及匹配原则

时间:2023-10-25 理论教育 版权反馈
【摘要】:重载函数常用来实现功能类似而所处理的数据类型不同的问题。编译器选择重载函数按实参类型与所调用的重载函数的形参类型一一比较并按下述3 个匹配原则的先后顺序来确定被调用的重载函数。定义重载函数时,为了提高程序的可读性,同名函数应该具有相同的功能。

面向对象程序设计中的重载函数用法及匹配原则

1.重载函数的概念

在C语言中,每个函数必须有一个唯一的名字,例如,求一个数的绝对值,由于不同类型的数据,则需要定义如下一组函数:

int abs(int);

long labs(long);

double fabs(double);

这些函数的功能都是用来求一个数的绝对值,只是所处理的数据类型不同。函数名不同,给使用带来很多麻烦。若是使用相同的函数名就会方便很多。为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个函数名对不同类型做出不同运算功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。

例如,上面的3个函数的声明可以改为:

int abs(int);

long abs(long);

double abs(double);

C++使用一种函数命名技术可以准确判断调用哪个abs()函数。例如:

abs(20); //调用int abs(int);

abs(34567L); //调用long abs(long);

abs(3.14159); //调用double abs(double);

2.重载函数的选择

在定义完一组重载函数之后,由于同一个函数名对应着多个不同的实现,在调用重载函数时,编译器如何确定调用的是哪个函数呢?编译器选择重载函数按实参类型与所调用的重载函数的形参类型一一比较并按下述3 个匹配原则的先后顺序来确定被调用的重载函数。

(1)查找一个严格的类型匹配;

(2)查找通过内部类型转换可以匹配的;

(3)通过用户定义的转换达到匹配的。(见6.3节)

例如,重载函数print()有以下两种:

void print(double);

void print(int);

对下列调用print()函数匹配情况如下:

print(7); //匹配void print(int);

print(7.4);//匹配void print(double);

print('a'); //匹配void print(int);

print(3.1415f); //匹配void print(double);

例如,对于如下两种形式的重载函数print()的定义:

void print(double);(www.daowen.com)

void print(long);

对print()函数的调用:

int a=1;

print(a); //错误,因为有二义性

重点提示

C++允许int到long,int到double 的转换。如果重载函数的形参中一个是long型,一个是double型,当实参是int型时,应该给出一个显示类型转换,否则在调用重载函数时将出现二义性错误。

3.重载函数的内部实现

C++使用一种被称为名称重整(name mangling)的技术来改变函数名,以区分不同的同名函数。在这种技术中,编译器通过把原函数名与其参数相结合产生一个唯一标识的内部名字来取代原函数名称。名称重整的方法是把原函数名变为“函数名”+“_”+“参数类型”的形式,即把一系列用以指示参数类型以及它们出现次序的代码附加到原函数名上。例如,用v,c,i,f,l,d,分别表示void,char,int,float,long,double,则重载函数:

int fun(int a);

double fun(double a,int b,char c);

经过名字重整后,函数名在内部分别被表示为:fun_i和fun_dic。

4.使用说明

(1)在定义重载函数时要求,要求同名函数在参数类型、参数个数、参数顺序和返回类型上有所不同,但仅仅返回类型不同是不能构成重载函数的。

例如,下面重载函数的声明是错误的:

void fun(double);

double fun(double);

编译器不能依据返回类型区分函数,因此重载函数至少要在参数类型、参数个数或参数顺序上有所不同。

【例1.9】形参类型相同但个数不同的函数重载。

程序中,main()函数中两个被调用的函数名称都是sum,形参类型也相同,但每个函数的参数个数不同,这样在调用时,会根据实参的个数自动选择与形参个数相同的函数。

(2)不允许使用typedef定义的类型名来区分重载函数中声明的参数,因为typedef并不能创建新的类型。例如:

typedef INT int;

int fun(int a)

{…}

INT fun(INT a)

{…}

这两个函数本质上属于同一个函数,算作重复定义,不能构成重载。

(3)定义重载函数时,为了提高程序的可读性,同名函数应该具有相同的功能。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈