赞
踩
1.剖析C++是如何实现重载的?
2.解析面试题:在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明?
1.函数重载的实现原理
函数重载的定义:当两个及两个以上函数共用一个函数名,但是形参个数或者类型不同,编译器根据实参与形参的类型及个数的最佳匹配,自动确定调用那一个函数。也就是说,在同一作用域,一组函数名相同,参数列表不同(个数和类型),返回类型可同,可不同的情况下,编译器根据调用者传入的参数类型和个数可以唯一可以唯一确定调用哪个函数.
如下代码:
- void OverloadFunc(intx,int d){}
- void OverloadFunc(intx, double d){}
- void OverloadFunc(doublex, int d){}
重载的底层原理
C++函数重载底层实现原理是C++利用倾轧技术,来改名函数名,区分参数不同的同名函数。
C++中,这三个函数如果在主函数中被调用选择哪一个,由编译器自身决定。 例如:
#include<iostream>
using namespace std;
int Add(int a, int b)
{
return a + b;
}
double Add(double a, double b)
{
return a + b;
}
int main()
{
int m = 10;
int n = 20;
double a=16.3;
double b=15.3;
cout << Add(m,n) << endl;
system("pause");
return 0;
}
这段代码两个函数Add参数的类型不同,在windows环境下Linux环境下编译器编译完成后的函数名的命名风格也就不同。以下是在VS2013编译器下编译完成map文件中的函数名,可以看出Add命名发生改变,一般是 ?[函数名]@@YAHHH@z(只用函数名和YA后面的格式和@z是固定的,剩下的都是固不定的,它的命名代了返回值的参数类型。(H—int,N—double,X—void)。
同样在linux环境下,这段代码中函数的命名也发生改变,一般是_Z[函数名长度][函数名][参数列表的类型首字母]。
总的来说:源文件通过编译后,将相同函数名,按照一定的格式,改变成可以区分的,去除了函数在调用时的二义性,从而实现函数的重载。
2.c++程序中调用被c编译器编译的函数时,为何后面加extern"C"声明
答:首先,extern是C/C++语言中表明函数和全局变量作用范围的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。extern "C"是连接申明(linkagedeclaration),被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:void foo( int x, int y);该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。
所以,可以用一句话概括extern “C”这个声明的真实目的:解决名字匹配问题,实现C++与C的混合编程。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。