名称的特殊处理
类成员变量的名称处理:
对于类的数据成员,其的名称经过编译器的处理会在程序员定义名称的后面再加上class
的名称,进而形成独一无二的命名,例如下面的的成员变量x
再经过类处理后有可能为x_7Point3d
。
class Point3d {
private:
double x{};
};
编译器之所以这么做,原因在于对于如下的派生操作,编译器内部形成的伪码可能如下注释的伪码所示。这样不管需要取哪一个x
,通过name mangling
处理后,都可以绝对清楚的指出。
class Point4d:public Point3d{
private:
double x;
};
// class Point4d{
// private:
// double x_7Point3d;
// double x_7Point4d;
// };
类函数对象的名称处理:
但是由于类成员函数支持重载,所以不能像上述对成员变量的处理一样只加上类名,需要加上额外的一些参数。对于一个类成员函数而言,其全局名称由类名、函数名称、参数个数、参数类型共同决定。
例如如下的函数,通过g++
编译运行结果会指示类成员函数的地址为0x4011a2
。通过nm
命令查看编译后的二进制文件,可以发现在ox4011a2
出存储的函数名为_ZNK7Point3d9normalizeEv
,这即是通过name mangling
得到的结果,但是因为目前没有统一的标准,因此不同编译器的处理方法会不太一样。
Point3d p(1, 2, 3);
auto p2 = p.normalize();
printf("成员函数normalize的地址: %p\n", &Point3d::normalize);