第8课 - 函数重载分析(上)
第8课 - 函数重载分析(上)
0. 自然语言中的上下文
你知道下面词汇中 "洗" 字的含义吗?
结论: ① 能和“洗”字搭配的词汇有很多 ② “洗”字和不同的词汇搭配有不同的含义
问题:C++ 作为一门高级语言,它应该向自然语言发展靠拢,更符合人的思维习惯。能否在其中添加重载的特性?
自然语言中:动词 + 名词 程序设计语言:函数 + 形参 【程序设计是一种哲学,一种思想,由生活而来】
1. 重载(Overload)的概念
(1)同一个标识符在不同的上下文有不同的意义
(2)如:
-
- "洗"和不同的词汇搭配后有不同的含义 √ 洗衣服、洗脸、洗脑、洗马桶。。。
- "play" 和不同的单词搭配后有不同的含义 √ play chess、play piano、play basketball。。。
2. C++中的函数重载(Function Overload)
2.1 函数重载的概念
(1)用同一个函数名定义不同的函数
(2)当函数名和不同的参数搭配时函数的含义不同
1 #include <string.h> 2 3 int func(int x) 4 { 5 return x; 6 } 7 8 int func(int a, int b) 9 { 10 return a + b; 11 } 12 13 int func(const char* s) 14 { 15 return strlen(s); 16 } 17 18 19 int main(int argc, char *argv[]) 20 { 21 printf("%d\n", func(3)); // 3 22 printf("%d\n", func(4, 5)); // 9 23 printf("%d\n", func("D.T.Software")); // 12 24 25 return 0; 26 }
2.2 函数重载需要的条件
函数重载必须满足下列条件之一:参数个数不同、参数类型不同、参数顺序不同
2.3 函数默认参数与函数重载
1 #include <stdio.h> 2 3 int func(int a, int b, int c = 0) 4 { 5 return a * b * c; 6 } 7 8 int func(int a, int b) // 两者从形式上确实构成了重载函数 9 { 10 return a + b; 11 } 12 13 14 int main(int argc, char *argv[]) 15 { 16 int c = func(1, 2); // ambiguous!!! 编译器也不知道调用哪一个,两者中的任何一个都满足,所以这里编译出错 17 18 return 0; 19 }
C++ 由于引入了很多特性,所以彼此之间会发生冲突,这里便是引发的第一个冲突。
2.4 编译器调用重载函数的准则
(1)将所有同名函数作为候选者
(2)尝试寻找可行的候选函数
-
- 精确匹配实参
- 通过默认参数能够匹配实参
- 通过默认类型转换匹配实参 // char --> int int --> char(可能溢出)
(3)匹配失败
-
- 最终寻找到的候选函数不唯一,则出现二义性,编译失败
- 无法匹配所有候选者,函数未定义,编译失败
2.5 函数重载的注意事项
(1)重载函数在本质上是相互独立的不同函数
(2)重载函数的函数类型不同
(3)函数返回值不能作为函数重载的依据
函数重载是由函数名和参数列表决定的!!!
1 #include <stdio.h> 2 3 int add(int a, int b) // int(int, int) 4 { 5 return a + b; 6 } 7 8 int add(int a, int b, int c) // int(int, int, int) 9 { 10 return a + b + c; 11 } 12 13 int main() 14 { 15 printf("%p\n", (int(*)(int, int))add); // 使用函数指针决定使用哪一个重载函数 16 printf("%p\n", (int(*)(int, int, int))add); 17 18 return 0; 19 }
在Linux下使用 nm工具 查看编译后的可执行程序的符号表,得到下面的结果,进一步证明了重载函数是相互独立的两个函数。
3. 小结
(1)函数重载是C++ 中引入的概念
(2)函数重载用于模拟自然语言中的词汇搭配
(3)函数重载使得C++ 具有更丰富的语义表达能力
(4)函数重载的本质为相互独立的不同函数
(5)C++ 中通过函数名和函数参数确定函数调用
注:本文整理于《狄泰12月提升计划》课程内容
狄泰QQ群:199546072