解析c++中函数重载的实现原理

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"声明

答:首先,externC/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的混合编程。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值