目录
重载:
重新赋予意义,可以认为是一词多义,例如:算账:基本义是计算账目;也指吃亏或失败后与人较量。八面玲珑:原指四面八方通明敞亮;也形容特例外观挺拔秀丽;多用来形容从处世圆滑或办事细致周到等意思。
函数重载:
是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这 些同名函数的形参列表(参数个数 或 类型 或者 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
- #include
- using namespace std;
-
- void F() { //无参
- cout << "F()" << endl;
- }
-
- void F(int a) { //带参
- cout << "F(int a)" << endl;
- }
-
- int main() {
- F();
- F(10);
- return 0;
- }
结果:
- void Swap(double* p1, double* p2) {
- double tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
- }
-
- void Swap(int* p1, int* p2) {
- int tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
- }
-
- int main() {
- int a = 10, b = 20;
- double c = 15.5, d = 20.6;
- Swap(&a, &b);
- Swap(&c, &d);
- cout << "a:" << a << " b:" << b << endl;
- cout << "c:" << c << " d:" << d << endl;
-
- return 0;
- }
结果:
-
-
- void F(int a, char b) {
- cout << "F(int a, char b)" << endl;
- }
-
- void F(char a, int b) {
- cout << "F(char a ,int b)" << endl;
- }
-
- int main() {
- F(10, 'A'); //输出第一个函数结果
- F('A', 20); //输出第二个函数结果
- return 0;
- }
结果:
注:顺序不同,是类型上的数据不同,而非是形参随意调换顺序!!如下:
- void F(int a, char b) {
- cout << "F(int a, char b)" << endl;
- }
-
- void F(char b,int a) {
- cout << "F(int a, char b)" << endl;
- }
这俩函数不构成重载,第二个函数的形参只是对调了一下顺序而已,其他完全一样。
例:
- void F() {
- cout << "Hello World" << endl;
- }
-
- void F(int a = 10, int b = 20) {
- cout << "Hello c++" << endl;
- }
-
- int main() {
- F(40);
- F(24, 73);
-
- F();
- return 0;
- }
解析:F(40); 会调用第二个F函数,那么a=40,b=20;
F(24,73); 会调用第二个F函数, a=24,b=73;
F(); 有歧义,它既符合第一个无参F函数的调用,也符合第二个全缺省F函数的调用(不放实参,默认使用缺省的形参值),这让系统为难,对重载函数调用不明确。
在学C语言时,它并不支持函数重载,在运行的时候时,会有三个阶段:预处理、编译、汇编。
1.预编译:在预编译阶段,编译器大致会做: 头文件的展开,删除注释,条件编译,宏替换生成test.i文件
2.编译:在编译阶段,编译器会:将C语言代码转换成汇编代码(test.s);进行语法分析,词法分析, 语义分析;符号汇总
3.汇编:在汇编阶段,编译器会把汇编代码转换成二进制指令(test.o),形成符号表.
4.链接:在链接阶段,链接器会合并段表;符号表的合并和重定位;找调用函数的地址,链接对应上,合并到一起最终生成可执行文件test.exe.
当C语言在编译过程生成符号表时,它的函数在符号表中的名字就只是用自定义的函数名来表示,所以,如果在C语言中写了函数重载,那么它会在符号表中生成两个名字一模一样的函数名,地址完全相同,那这样在链接的过程中它的符号表中会有两个完全一样的函数名地址,那编译器不知道该找哪个。
所以,这个时候就发生了错误.这也就是C语言不能支持重载的原因.
C++设计了一个函数名修饰规则,用函数名+参数类型为标准去区分各个重载函数的不同。C语言对函数名没有任何修饰,只有一个地址;而C++对函数名做了一定修饰,参数不同,修饰出来的名字就不同!!!如下图是Linux系统中g++编译器(针对C++语言的)修饰方法:
-
- int F(int a, char b) {
- std::cout << "F(int a, char b)!" <
- return 0;
- }
-
- char F(int a, char b) {
- std::cout << "F(int a, char b)" << std::endl;
- return 'A';
- }
-
- int main() {
- F(10,'a');
- F('a',10);
- return 0;
- }
如上题代码所示,返回值不同,能不能构成函数重载?
答案:不能,函数重载取决于参数的个数,类型,顺序。而和返回值类型无关,所以仅仅是返回值的不同,并不构成重载原因,——返回值的不同并不是函数修饰的规则
真正的原因是:函数调用的二义性,编译器无法区分该选哪个去用,所以调用时并不指定返回值类型。