【C++】-- 命名空间、函数重载、内联函数(二)

简介: 【C++】-- 命名空间、函数重载、内联函数

四、函数重载

c语言不允许定义同名函数,但是c++能够通过函数重载定义同名函数

1.函数重载概念

C++中重载函数通常用来命名一组功能相似而数据类型不同的函数:函数重载是指在同一作用域内,一组函数名相同,不同参数列表(不同参数个数 或 不同类型 或 不同顺序)的函数,这组函数被称为重载函数。

函数重载作用:减少了函数名的数量,避免了名字空间的污染,增加了程序可读性。

如下3个Add函数构成重载,它们的参数类型都不相同,参数类型分别是int、double、long

1. #include<iostream>
2. 
3. int Add(int left, int right)
4. {
5.  return left + right;
6. }
7. 
8. double Add(double left, double right)
9. {
10.   return left + right;
11. }
12. 
13. long Add(long left, long right)
14. {
15.   return left + right;
16. }
17. 
18. int main()
19. {
20.   Add(10, 20);
21.   Add(10.3, 20.5);
22.   Add(10L, 20L);
23. 
24.   return 0;
25. }

注意1:函数是否重载取决于同名函数参数列表是否相同,函数重载和函数返回值类型没有关系。

如下两个函数不是函数重载,编译会报错,因为参数列表相同,不构成重载,尽管返回值类型不同,但函数重载定义并不关注返回值类型。

1. int Add(short left, short right)
2. {
3.  return left + right;
4. }
5. 
6. short Add(short left, short right)
7. {
8.  return left + right;
9. }

注意2:带缺省参数的函数和原函数不算重载

如下两个函数参数类型、个数、顺序都相同,不构成重载

1. int Add(int left, int right)
2. {
3.  return left + right;
4. }
5. 
6. int Add(int left = 2, int right = 3)
7. {
8.  return left + right;
9. }

另外,虽然下面的两个f函数构成重载,但是调用时报错,因为16行对f函数进行调用时,编译器并不知道是该匹配两个参数的f函数还是该匹配带有缺省参数c的f函数,因此会报错。

1. void f(int a, int b, int c=1)
2. {
3. 
4. }
5. 
6. void f(int a, int b)
7. {
8. 
9. }
10. 
11. int main()
12. {
13.   f(1, 2);
14.   f(1, 2, 3);
15. 
16.   return 0;
17. }

2.c++支持重载的原因

c/c++编译过程:

在linux环境中,创建f.h文件,写如下代码:  

创建f.cpp文件,写如下代码:

创建main.c文件,写如下代码:

执行g++ -o cpp f.cpp main.cpp

编译通过,生成cpp可执行文件

执行objdump -S cpp

生成汇编代码:

main.cpp的#include "f.h"包含了f.h文件,f.h文件只是包含了两个add函数的声明,在编译阶段,编译器会认为函数定义在其他地方,而让函数编译通过,等到链接时,再找函数的定义。

链接时,通过函数名即函数地址去其他目标文件中找add的地址,如果找到了就填上add的地址。

根据c++函数名修饰规则,只要参数不同,修饰出来的函数名就不同,这就支持了重载:把参数类型首字母带进函数名中,参数不同,函数签名就不同。

_Z3addii函数名中,_Z是前缀,3是函数的字符长度(add长度为3),ii是两个参数类型int的首字母

同理,_Z3adddd函数名中,_Z是前缀,3是函数的字符长度(add长度为3),dd是两个参数类型double的首字母。

以上也能看出c++函数签名和返回值类型无关。

那么,对于c语言直接拿函数名做名称,无法支持定义两个同名函数

f.h

f.c

main.c

执行 执行g++ -o test f.cpp main.cpp

编译通过,生成test可执行文件

执行objdump -S test

生成汇编代码:

C语言无法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,这就支持了重载。

相关文章
|
11天前
|
C++
C++命名空间(namespace)的使用
C++命名空间(namespace)的使用
|
13天前
|
存储 编译器 C语言
【C++入门】—— C++入门 (下)_内联函数
【C++入门】—— C++入门 (下)_内联函数
13 2
|
13天前
|
人工智能 安全 编译器
【C++入门】—— C++入门 (上)_命名空间
【C++入门】—— C++入门 (上)_命名空间
16 2
|
2天前
|
Unix 编译器 C语言
【C++航海王:追寻罗杰的编程之路】关键字、命名空间、输入输出、缺省、重载汇总
【C++航海王:追寻罗杰的编程之路】关键字、命名空间、输入输出、缺省、重载汇总
5 0
|
3天前
|
存储 安全 编译器
【C++】:函数重载,引用,内联函数,auto关键字,基于范围的for循环,nullptr关键字
【C++】:函数重载,引用,内联函数,auto关键字,基于范围的for循环,nullptr关键字
10 0
|
3天前
|
编译器 C语言 C++
【C++】:C++关键字,命名空间,输入&输出,缺省参数
【C++】:C++关键字,命名空间,输入&输出,缺省参数
10 0
|
9天前
|
编译器 C++
C++对C的改进和拓展\域解析符、形参默认值、函数重载
C++对C的改进和拓展\域解析符、形参默认值、函数重载
7 0
|
3天前
|
安全 编译器 C++
【C++】学习笔记——类和对象_5
【C++】学习笔记——类和对象_5
17 9
|
2天前
|
存储 编译器 C语言
【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(上)
【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(上)
8 2
|
2天前
|
C++
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
2 0
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)