C++--问题4--重载
1.c++函数重载的定义
在同一作用域类,一组函数的函数名相同,参数列表不同(参数个数不同或者参数类型不同),返回值可同可不同。
2.函数重载的作用
重载函数通常用来在同一个作用域内,用同一个函数名命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。
3.函数重载是一种静态多态
(1)多态:用同一个东西表示不同的形态。
(2)多态分为:
静态多态:编译时的多态
动态多态:运行时的多态
(3)函数重载是一种静多态。
4.c++函数重载的原理:
编译器在编译.cpp文件中当前使用的作用域里的同名函数时,根据函数形参的类型和顺序会对函数进行重命名(不同的编译器在编译时对函数的重命名标准不一样)但是总的来说,他们都把文件中的同一个函数名进行了重命名;
在vs编译器中: 具体命名方式见5.
根据返回值类型(不起决定性作用)+形参类型和顺序(起决定性作用)的规则重命名并记录在map文件中。
在linux g++ 编译器中:
根据函数名字的字符数+形参类型和顺序的规则重命名记录在符号表中;从而产生不同的函数名,当外面的函数被调用时,便是根据这个记录的结果去寻找符合要求的函数名,进行调用;
5.为什么c语言不能实现函数重载
答:命名方式不同,C的太简单,所以不能实现函数重载。编译器在编译.c文件时,只会给函数进行简单的重命名;具体的方法是给函数名之前加上”_”;所以加入两个函数名相同的函数在编译之后的函数名也照样相同;调用者会因为不知道到底调用那个而出错。
程序在链接时,生成符号表,在.c程序中,看看函数名在符号表中的命名:
通过这个我们可以得出,c程序中的Add()函数在符号表中的重命名就是函数名前边加个下划线。所以如果一个c程序中出现了同名函数,他们在符号表中的命名一样,这样调用时就出现了冲突。
改为.cpp文件,编译之后在map中查看两个Add()函数的名字:
我们可以看出,在.cpp文件中,虽然两个函数的函数名一样,但是他们在符号表中生成的名称不一样。
注:‘?’表示名称开始,‘?’后边是函数名,“@@YA”表示参数表开始,后边的3个字符分别表示返回值类型,两个参数类型,“@Z”表示名称结束。
由于在.cpp文件中,两个函数生成的符号表中的名称不一样,所以是可以编译通过的。
6.在c++程序中调用被C编译器编译后的函数,为什么要使用extern “C”?
答: C++语言支持函数重载,C语言不支持函数重载,C++语言为了支持重载,对编译时函数的重命名规则进行更改, 使用extern “C” 的方式在C++程序中声明C语言文件中的函数,可以在编译时,告诉编译器使用C语言的规则对该函数的的函数名的进行重命名,这样在链接的时候,就可以顺利在.c文件中找到该函数。
使用extern "C" int Add(int,int); 外部函数—正确,在.cpp文件中代码如下:、
#include<iostream>
using namespace std;
extern "C" int Add(int,int);
int main()
{
cout<<Add(50,50)<<endl;
return 0;
}
结合多态和虚函数,会更容易学懂,可查看我的其他博客哟~