9

C++重载底层原理 - 牛犁heart

 1 year ago
source link: https://www.cnblogs.com/whiteBear/p/17180339.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

C++重载底层原理

好吧,承认是自己浅薄了
当被问起C++重载时,嘴角不自觉的微微上扬,然后脱口而出,C++重载的原则:

  • 函数名相同,函数参数列表不同(类型、个数、顺序)
  • 匹配原则1:严格匹配,找到再调用
  • 匹配原则2:通过隐式类型转换寻求一个匹配,找到则调用
  • 注:返回类型不构成重载条件

C++编译时多态也是由重载函数来实现的,那既然扯到多态了,顺便也把运行时多态(虚函数)相关的东西简单了说了下

结果谁成想,反手就问了C++重载的底层实现原理是怎样的?

这。。。瞬间蒙蔽

或者问:为什么C没有重载,C++有重载


------不华丽的分割线------


先说结论:
C++针对函数名有经过一种叫Name Mangling的特殊处理,网上很多都是翻译成了命名倾轧
成员函数的函数名会经过Name Mangling处理,得到一个程序中独一无二的词汇。

  • Name Mangling对成员变量的处理,一般会在变量名称前加上类名称,形成独一无二的命名。
    举例:
class Bar{public: int ival;...}

其中的ival有可能变成:

ival_3Bar

PS:这个结果,可能会因为编译器的编码方法不同而不同。

  • 针对成员函数,为让它们独一无二,唯有再加上它们的参数列表
    举例:
class Point{
public:
	void x(float newX,int newY);
	void x(int newY, float newX);
	float x();
	...
}

它可能转换为:

class Point{
public:
	void x_5PointFfi(float newX, int newY);
	void x_5PointFif(int newY, float newX);
	float x_5PointFv();
	...

}

这也就解释了为什么C++重载对参数类型、顺序、数量作为重载的原则。

至于C为什么不能重载,那是因为编译器只是对函数名做了独一无二的命名处理,并没有带上参数相关的信息。

另:
如果声明了extern "C",就会禁止命名倾轧name mangling的效果。


------不华丽的分割线------


一个完整的C++编译过程(例如g++ a.cpp生成可执行文件),总共包含以下四个过程:

  • 编译预处理,也称预编译,可以使用命令g++ -E执行
  • 编译,可以使用g++ -S执行
  • 汇编,可以使用as 或者g++ -c执行
  • 链接,可以使用g++ xxx.o xxx.so xxx.a执行
#  -E 编译器对文件进行预处理
g++ -E test.cpp -o test.i     //i文件
#  -S编译器告诉g++再为c++代码产生汇编语言后停止编译
g++ -S test.i -o test.s    
#  -c 选项告诉g++仅把源代码编译为机器语言的目标代码
g++ -c test.s -o test.o    (-c小写)
#    -0 产生可执行文件名

g++ test.0 -o test
写代码来看下:

image

通过g++ -c会将源代码编译成机器语言的目标代码,然后使用objdump -t 目标文件将二进制文件进行反汇编,具体如下:

image

其中,_Z是规定前缀,4是函数名的字符个数,i是参数列表类型i的首字母

C++也提供了命名反倾轧
1.将名字改编转化成函数名
使用c++filt命令可以很容易把名字改编转换成函数名

c++filt _Z4funci
  1. 查看反倾轧的符号表
    有两种方式:
  • nm -C 目标文件

  • objdump -t -C 目标文件
    结果如下:

    image

可参考:
绝对强大的三个linux指令: ar, nm, objdump


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK