//test.hvoidFunc(int a, int b, int c);
//test.c#include"test.h"voidFunc(int a = 10, int b = 20, int c = 30){
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
//main.c#include"test.h"intmain(){
Func();
return0;
}
voidSwap(int* a, int* b){
int num = *a;
*a = *b;
*b = num;
}
voidSwap(double* a, double* b){
double num = *a;
*a = *b;
*b = num;
}
intmain(){
int a = 10, b = 20;
Swap(&a, &b);
cout << "a = " << a << " b = " << b << endl;
double c = 10.12, d = 20.12;
Swap(&c, &d);
cout << "c = " << c << " d = " << d << endl;
return0;
}
运行结果:
这样我们就完成了不同类型的变量交换,Swap 函数形成了重载,这时 C++ 编译器特有的属性
构成重载的三大要素:
形参个数不同
形参类型顺序不同
形参类型不同
注意:函数的返回值不同是不构成函数重载的!!
4.1、深入了解 C++ 的重载机制
在深入了解之前,我们先认识一下 C 语言为什么不支持重载,但在此之前我们需要清楚 C/C++ 的程序编译与链接,因为重载机制的核心是发生在编译阶段完成的。
在 C 语言中,我们根据程序编译与链接笔记可以知道,在程序在经过编译后我们的函数符号名是不会有改变的。我们以下程序为例:
#include<stdio.h>voidSwap(int* a, int* b){
int num = *a;
*a = *b;
*b = num;
}
intmain(){
int a = 10;
int b = 20;
Swap(&a, &b);
printf("%d \n", a);
return0;
}
我们在 Linux 环境下查看上面 C 语言生成的符号表。
在上图中,可以清晰看出在C 语言中,函数符号名有且只有一个,这样就导致了 C 语言的编译器不支持重载,而C++ 则推出了全新玩法:把编译后的函数符号名更改为另一种形式函数符号名,让其实现函数的重载。
在 Windows 环境下,函数命名太过复杂,这里使用 g++编译器。
我们以上面代码为例:
#include<stdio.h>voidSwap(int* a, int* b){
int num = *a;
*a = *b;
*b = num;
}
intmain(){
int a = 10;
int b = 20;
Swap(&a, &b);
printf("%d \n", a);
return0;
}
我们在 Linux 环境下,查看由 g++ 编译器编译后所形成的符号表,查看函数符号名的变化。
此时 C++ 中的函数,已经不再是单纯的 Swap,而是在 Swap 前后增加了新东西。那一前一后的东西需要查看对应编译器的命名规则,如下。
C++ 的函数符号名命名规则:
每个编译器都有自己的函数名修饰规则
g++ 编译器中的函数修饰后变成【_Z+ 函数长度 + 函数名 + 类型首字母】
Windows 下名字修饰规则
根据命名规则我们可以得出交换函数 Swap 在 C++ 形成 _Z4SwapPiS_ 代表着:
_Z:固定开头
4:代表着函数名字的长度,Swap 长度 4 个字符,所以是 4
Swap:代表了函数名
Pi:代表了 int* 类型的首字母合体,P代表是指针,i代表是整形。
voidf(int a, char b){
cout << "f(int a, char b)" << endl;
}
voidf(char b, int a){
cout << "f(char b, int a)" << endl;
}
voidf(int a, double b, char c){
cout << "f(int a, double b, char c)" << endl;
}
intmain(){
f(10, 'a');
f('a', 10);
f(10, 2.5, 'a');
return0;
}
我们使用 g++ 编译器,生成符号表查看上面函数 f 的符号名。
第一个函数 f:后面的类型是 i 与 c,对应形参中的 int 与 char;
第二个函数 f:后面的类型是 c 与 i,对应形参中的 char 与 int;
第三个函数 f:后面的类型是 i、d 与 c,对应形参中的 int、double 与 char;
通过这里就理解了 C 语言没办法支持重载,因为同名函数没办法区分。而 C++ 是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。