初识C++之函数重载

来源:互联网 发布:c语言求100以内素数 编辑:程序博客网 时间:2024/04/28 15:06

最近开始学习C++,了解到它在C语言没有的一个特性 – 函数重载,这一特性使得c++的函数数量得以减少,减小了对名字空间的污染,另外对程序的可读性也有很大帮助。

那么c++的函数重载这一特性是怎么实现的,为什么不会发生命名冲突呢?别的函数在调用这些函数时编译器是怎么解析的呢?怎么知道它该调用哪一个函数呢?下面就这些问题来做一些简单解析。

1、什么是函数重载

C++允许在同一作用域内声明并实现几个名称相同,功能相似的函数,但必须保证这些函数的参数列表不同(参数个数不同、参数类型不同或者参数顺序不同)

根据上面的定义,判断哪些是正确的函数重载,哪些是错误的:

int Add(int a, int b){    return a + b;}double Add(double a, double b){    return a + b;}

double Add(double a, int b){    return a + b;}double Add(int a, double b){    return a + b;}

int Add(int a, int b){    return a + b;}int Add(int a, int b, int c){    return a + b + c;}

double Add(int a, double b){    return a + b;}double Add(int b, double a){    return a + b;}

int Add(int a, int b){    return a + b;}double Add(int a, int b){    return a + b;}

①②③很容易得出都是正确的函数重载;
④乍一看,很像是满足了参数顺序不同这一条件,但仔细分析一下,函数在定义或声明是是可以省略参数名的,因为编译器只检查函数参数的类型与个数,并不会检查函数名。那么,④的两个函数就可以看做是一个,因为它们无法构成函数重载;
⑤看起来也很像啊,但它满足函数重载的任何要求了吗,另个函数参数列表完全是一样的,唯一不一样的就是函数的返回值不同,但仅仅返回不同是无法构成函数重载的的,因此,它们也无法构函数重载。

2、为什么需要函数重载

想一想我们的C语言里是怎么定义不同类型的数据的加法函数的:

int Add(int a, int b); –> int 型数据的加法函数
short Add(short a, short b); –> short 型数据的加法函数
double Add(double a, double b); –> double 型数据的加法函数

是不是感觉很麻烦,都是同一功能的函数,却要起不同的名字,正式基于这一点,c++允许实现函数重载,这样不仅同一功能的函数都能叫同一名字,而且节省了名字空间。

3、编译器如何解决函数重载的命名冲突

c++确实能支持函数重载,但编译器是怎么处理这种特性,使它们在编译后不会出现名字冲突的呢?

这里可以参考我的另一篇博客:
重载函数编译后的新名字
http://blog.csdn.net/ljx_5489464/article/details/50981773

4、编译器如何解析重载函数的调用呢?

上面我们知道了,编译器通过一定的机制使重载函数在编译后不会发生名字冲突,那么在调用这些重载的函数时,编译器是如何知道该调用哪一个的呢?

编译器一般需要依次按照下列规则来判断:
a. 精确匹配:参数列表完全匹配,或者只是做微不足道的转换,如数组名到指针、函数名到指向函数的指针、T到const T;
b. 提升匹配:即整数提升(如bool 到 int、char到int、short 到int),float到double
c. 使用标准转换匹配:如int 到double、double到int、double到long double、Derived*到Base*、T*到void*、int到unsigned int;
d. 使用用户自定义匹配;
e. 使用省略号匹配:类似printf中省略号参数

通过以上规则来进行选择:
①根据函数名确定候选函数集
②确定可用函数
③确定最佳匹配函数

如果在最有多个最佳匹配函数找到,调用将被拒绝(因为有歧义、模凌两可)。

本文参考:
http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html

0 0
原创粉丝点击