初识C++之函数重载
2016-03-25 16:44
351 查看
最近开始学习C++,了解到它在C语言没有的一个特性 – 函数重载,这一特性使得c++的函数数量得以减少,减小了对名字空间的污染,另外对程序的可读性也有很大帮助。
那么c++的函数重载这一特性是怎么实现的,为什么不会发生命名冲突呢?别的函数在调用这些函数时编译器是怎么解析的呢?怎么知道它该调用哪一个函数呢?下面就这些问题来做一些简单解析。
1、什么是函数重载
C++允许在同一作用域内声明并实现几个名称相同,功能相似的函数,但必须保证这些函数的参数列表不同(参数个数不同、参数类型不同或者参数顺序不同)
根据上面的定义,判断哪些是正确的函数重载,哪些是错误的:
①
②
③
④
⑤
①②③很容易得出都是正确的函数重载;
④乍一看,很像是满足了参数顺序不同这一条件,但仔细分析一下,函数在定义或声明是是可以省略参数名的,因为编译器只检查函数参数的类型与个数,并不会检查函数名。那么,④的两个函数就可以看做是一个,因为它们无法构成函数重载;
⑤看起来也很像啊,但它满足函数重载的任何要求了吗,另个函数参数列表完全是一样的,唯一不一样的就是函数的返回值不同,但仅仅返回不同是无法构成函数重载的的,因此,它们也无法构函数重载。
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
那么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
相关文章推荐
- C++中关于get()和getline()函数读取行的问题
- hjr-四旋翼飞行器串级PID飞控算法
- Warning: ISO C++11 does not allow conversion from string literal to 'char*'
- 加入c++里的cin和cout则又不行了
- C语言第九篇:各种输出小星星(循环控制)
- C++中有关数组的一些细节问题
- C++实验2-学生成绩
- 【C/C++】:用C实现输出日期的阴历日子
- DEV C++ "把着手教" 单步调试(debug)
- 俄罗斯方块c++
- C语言指针与数组易混淆知识点(一)
- c++ 类的使用 友元函数 重载运算符
- C++的引用的一个测试例子
- c++第二次作业2
- c++11 学习及测试(虚继承 虚函数时类的内存分布)
- C++面试点2
- C++ map的基本操作和使用
- C++ primer中有很多好玩的东西
- C++学习的一些经历
- c语言:双向链表的实现