课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
深圳达内告诉你如何使用C++增加普通成员方法 ,深圳IT培训(sz.tedu.cn)专家就针对如何使用C++增加普通成员方法 这一问题做一个详细的分解。希望能在工作中对你有所帮助!
如果增加一些方法,会影响到类的大小吗?我们可以看一下下面的示例代码,
Listing 4 - add methods
1 class A { 2 public: 3 A(int i, char j, float k) : a(i), b(j), c(k) {} 4 5 int GetA() { return a; } 6 char GetB() { return b; } 7 float GetC() const { return c; } 8 9 private:10 int a;11 char b;12 float c;13 };1415 int g_a = 100;16 int GetA() { return g_a; }1718 int main() {19 A t(0x12345678, 'b', 12.5);20 printf("sizeof(t) = %ld\n", sizeof(t));21 HexDump(&t);22 t.GetA();23 GetA();24 return 0;25 }// output as below:// sizeof(t) = 12// 0x7fffa6f5e2c0: 0x78 0x56 0x34 0x12 0x62 0x00 0x00 0x00 // 0x7fffa6f5e2c8: 0x00 0x00 0x48 0x41
从输出结果,我们可以看到,引入方法定义,并不会改变内存布局。细心的读者可能发现,我们多定义了一个全局函数 GetA() 。这里主要是想多聊几句类的成员方法。这些成员方法和普通的全局函数有什么不一样呢?我们主要从函数名和用法两个方面来看。
从函数名或者函数原型来看,C++ 为了支持函数重载,所以对编译出的函数名符号进行了 name mangling [4],通过 nm/objdump 结合 c++fillt ,我们可以还原函数名,具体如下。可以看出来,类名也是函数名的一部分,所以可以区别于全局同名函数。
Listing 5 - nm
$ nm a.out000000000040057d T _Z4GetAv000000000040061e W _ZN1A4GetAEv00000000004005e8 W _ZN1AC1Eicf
Listing 6 - name mangling
$ nm a.out | c++filt -n000000000040057d T GetA()000000000040061e W A::GetA()00000000004005e8 W A::A(int, char, float)
除了函数名之外,具体使用上来看,类方法需要通过对象来调用,具体到汇编层面,可以看到类的方法接收的第一个参数是对象的地址( this 指针):
Listing 7 - method member call
leaq -16(%rbp), %rax => 对应栈地址&tmovq %rax, %rdi => %rdi为函数第一个参数[5]call _ZN1A4GetAEv => t.GetA()call _Z4GetAv => GetA()
想知道更多关于IT行业的信息吗?想远远不如行动,行动起来,一起加入达内,一起进入IT行业,跟着达内的脚步,一起走进如今的互联网信息时代,带给你不一样的色彩生活——【深圳IT培训】