C++中函数重载的底层原理

一、C++中函数重载规则

函数重载是一种特殊情况,C++允许在同一作用域中声明几个类似的同名函数,这些同名函数的形参列表(参数个数,类型,顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。

 

二、C++函数重载的底层原理

C++利用name mangling(倾轧)技术,来改变函数名,区分参数不同的同名函数

1. Name Mangling 简介

Name Mangling 是一种在编译过程中,将函数、变量的名称重新改编的机制。在 C++重载、namespace等操作符下,函数可以有同样的名字,编译器为了区分各个不同地方的函数,将各个函数通过编译器内定的算法,将函数改成唯一的名称

用v c i f l d表示void char int float long double 及其引用。

 如: void func(char a);             //func_c(char a)

    void func(char a,int b,double c);     //func_cid(char a,int b,double c)

除此之外,这种编码必须简单,而且要可逆,就是能由全局名称很快的知道局部的名称。

2.C中的name mangling

如:void foo(int x, int y);
该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int;所以在编译之后C仍然无法辨别函数名相同、参数不同的函数。

虽然Name Mangling技术不太用于不支持函数重载的语言中,例如C和经典Pascal,但是在某些场景下,除了名字之外,还需要其他的信息。例如多数编译器都支持多种不同的调用惯例(calling conventions),调用惯例决定了函数参数的入栈方式以及由哪一方负责来清理栈帧。这就需要将函数的调用惯例信息有编译器附加到目标文件的符号名中

例如:

int _cdecl    f (int x) { return 0; }
int _stdcall  g (int y) { return 0; }
int _fastcall h (int z) { return 0; }

 

然后对应的符号名有可能是:

_f
_g@4
@h@4

(该部分内容源自:电影旅行敲代码)


三、C++的函数按照C的风格来编译

C++中可以通过在函数声明前加 extern "C" 将一个函数按照 C 语言的风格来进行编译。

(在看C++的时候,看到了“重载”。脑子一短路忘记了,就来看博客,真的学了蛮多的。而且我在很多篇博客里面看到,这类的问题可能是面试题??!)

你可能感兴趣的:(深究C++)