相同点和不同点分成两篇文来写,因为不同点会涉及继承等略复杂的特性。此外Java不支持运算符重载这个特性也差不多是“人尽皆知”了。
这篇分为两部分,如何进行方法重载及基本类型提升和窄化。
一. 如何进行方法重载?
c++和Java的要求是一样的,即:方法名相同,形参列表不同。这个要求其实也就是编译器对方法重载的区分方式。
方法名相同自不必多说,形参列表不同的含义为以下三层:
1.参数数量不同;
2.参数数量相同但参数类型不同;
3.参数数量与类型均相同,那么参数顺序必须不同。
可以看出,这三层严格度1>2>3。
要注意,以下方式不能区分不同的方法重载(即当不满足上述3个条件均不满足时,下列方式不能作为区分方法重载的方式,亦即下列方式非方法重载)
1.返回值不同;
2.形参表中参数名称不同。
如果要记的话,只需记住能区分重载的三个条件即可。三条以外的其他方式均不可。
但是非常不推荐死记硬背。如果理解了为何是这三个条件而不是其他,自然也就记住了。
下面来解释如何区分不同的方法重载。
看下面这个方法(函数)
int fun(int a,int b);
在编译时,编译器会生成一个类似"_fun_int_int"的名称放在库中,可以看出,这个名称是方法名+形参列表中的所有参数类型合成的,这也是对方法重载的唯一区分方式。
可以看出返回值类型、形参名并没有包含在这个名称中,因此返回值和形参名并不能区分不同的方法重载。
特别地,对于形参顺序不同的方法能够很好地区分,例如:
int fun(int a,double b);编译生成的名称分别为"_fun_int_double"和"_fun_double_int",名称不同而得以区分。
int fun(double b,int a);
二. 基本类型的提升与窄化
当给方法传入的实际参数类型小于方法中声明的形参类型,将会被提升至形参的类型。如果有方法重载,则会提升至待转换类型与所有方法可以接受的“最近的”类型。例如:
char* fun(long a) {return "long";}当如下调用fun时
char* fun(float a) {return "float";}
char* fun(double a) {return "double";}
cout<<fun(5);
输出结果为
long可以看出,常数5被当作一个int类型的值来处理,当调用方法fun时,由于所有的重载中都没有能接受int类型的方法,因此5将会被提升至最近的long类型。
唯一的例外是char类型,如果没有能恰好接受char类型的方法,就会把char类型直接提升为int类型。
对于上面的例子,如果传入char类型,则会被提升至int类型,又因为没有能接受int类型的方法,则又被再次提升至long类型,经历了char->int->long的提升过程。
类型窄化同理,也是被窄化至“最近的”类型,不存在例外情况。