您的位置:首页 > 编程语言 > C语言/C++

初识C++之函数重载

2016-03-25 16:44 351 查看
最近开始学习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++确实能支持函数重载,但编译器是怎么处理这种特性,使它们在编译后不会出现名字冲突的呢?

这里可以参考我的另一篇博客:

重载函数编译后的新名字

/article/9643182.html

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中省略号参数

通过以上规则来进行选择:

①根据函数名确定候选函数集

②确定可用函数

③确定最佳匹配函数

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

本文参考:

/article/4698724.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: