主页 > 电脑硬件  > 

C++函数重载

C++函数重载

目录

一、函数重载:

二、C++支持函数重载的原理:

三、再谈函数重载:


一、函数重载:

        C语言不允许函数同名,但是C++可以,需要构成函数重载。函数重载是函数参数类型不同,或者参数个数不同,或者参数类型顺序不同。

//函数重载 //参数类型不同 int Add(int x, int y = 10) { return x + y; } //参数个数不同 float Add(float x, float y, int z) { return x + y + z; } //参数类型顺序不同 double Add(double x, int y) { return x + y; } int main() { //匹配第一个函数 cout << Add(10) << endl;//打印结果为:20 //匹配第二个函数 cout << Add(3.14, 9.07, 10) << endl;//打印结果为:22.21 //匹配第三个函数 cout << Add(10.89, 30) << endl;//打印结果为:40.89 return 0; }

        函数返回值不同不能构成重载,两个命名空间的完全相同的函数不构成函数重载,只有在同一命名空间下才可能会构成函数重载。

二、C++支持函数重载的原理:

1)C语言不支持函数重载,而C++支持函数重载,这是因为与编译链接有关。

2)C语言的编译链接过程经过预处理、编译、汇编、链接四个阶段,C++的编译链接过程和C语言的大致相同。

预处理阶段:在预处理阶段,执行了头文件展开、去注释、宏替换、条件编译等,此过程处理的文件是.cpp文件,生成.i文件。

编译阶段:编译阶段执行了语法检查、语义检查等,此过程生成.s文件,也就是汇编代码(指令级代码)。

汇编阶段:汇编阶段将汇编代码转换成二进制机器码,形成符号表。在VS中,汇编阶段生成的目标文件是.obj文件,gcc中,生成的目标文件是.o文件。

链接阶段:生成.exe的可执行文件,该过程完成了合并段表、符号表的合并和重定位。

3)符号表:

        在汇编阶段生成的符号表中,存在着变量或函数与地址的一一映射。C语言中是使用变量名或函数名充当变量或函数的地址,而C++中,会有变量名和函数名与它们的地址一一映射(即C语言使用名字充当地址,C++通过函数名找地址),尽管变量或函数名字相同,但它们的地址并不相同,每个地址都是唯一的,这就导致C语言不支持变量与函数重名,而C++可以存在重构函数。

        C++有一个函数名修饰规则,每一个函数被赋予了一个新的函数名(修饰以后的函数名),当有同名的函数构成函数重载时,它们的新函数名并不相同,所以C++允许函数重名。

//函数名修饰规则 //这里只给出函数声明,没有函数定义,主要是为了观察VS中的函数名修饰规则 void func(int a, double b); void func(double b, int a); int main() { func(10, 3.14); func(3.14, 10); return 0; }

        这也就是为什么构成重载的函数,编译器同样知道该调用哪个函数,因为它们的新函数名有点不同,一个中间是HN,另一个是NH,也可以看出VS使用H代表int类型,N代表double类型。

        那为什么函数只有声明没有定义的话,调用函数就会报错呢?因为函数没有定义就不会生成地址,使用新函数名去找这个地址的时候,就找不到。所以错误信息是无法解析的外部符号。

三、再谈函数重载:

        为什么函数重载只有参数类型不同、参数顺序不同、参数个数不同这三种方式,上面的函数名修饰规则已经讲清楚了。

那么如果通过函数名修饰规则,设计出两个除了返回值类型不同,其余都相同的函数,它们可以构成函数重载吗?答案是否定的,因为对于这两个函数而言,确实可以创造出两个不同的新函数名,但是调用函数时候怎么办呢,两个调用的函数无论是传参的类型还是函数名都完全一样,编译器要怎么区分呢?除非把调用规则也修改了。

标签:

C++函数重载由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C++函数重载