1.剖析C++是如何实现重载的?
在C语言中,实现功能相同,但参数数量或类型不同的函数,函数名必须不同,例如:
double Add1(double a, double b);
int Add2(int a, int b);
C++是C语言的继承,c++在c语言的基础上新增了很多特性,其中具有重载。例如,上述的Add函数就可以如下命名:
double Add(double a, double b)
{
return a + b;
}
int Add(int a, int b)
{
return a + b;
}
这五个函数中,参数数目的、参数类型和参数的排列顺序就是函数的参数列表,也称为函数特征标,在使用Add函数时,编译器会根据所采取的用法使用有相应特征标的原型:
例如:
例如:
int main()
{
int a1 = 3, b1 = 4, c1 = 0;
double a2 = 3.1, b2 = 4.1, c2 = 0;
c1 = Add(a1, b1);
c2 = Add(a2, b2);
cout << c1 << endl << c2 << endl;
}
运行结果如下:
7
7.2
如上述所述,编译器会根据特征标的不同,来分辨该使用哪个函数,在编译过程中,他采用了对重载函数进行解析然后映射到一个新的标识符。
double Add(double a, double b) ?Add@@YANNN@Z
int Add(int a, int b) ?Add@@YAHHH@Z
double Add(double a, double b,double c) ?Add@@YANNNN@Z
double Add(double a, double b) ?Add@@YANNN@Z
void Add(double a, double b,double c) ?Add@@YAXNNN@Z
可以根据编译后可来判断,映射为
函数名+返回类型+参数列表
。
不同的编译器有不同的重命名方式,这里仅仅举例说明,实际情况可能并非如此。从这个角度讲,函数重载仅仅是语法层面上的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。
2.解析面试题:在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明?
因为C++语言和C语言对编译后的函数符号和外部变量符号的修饰方式不一样,代码编译过后,连接器解析外部符号的时候就会出现无法解析外部符号的错误。你加上extern "C"之后,C++编译器就会按照C语言的符号修饰规则对函数进行修饰,这样连接器就能够正确解析。