开发环境
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
1, ObjectSliced
当一个base class object 被直接初始化(copy ctor)/赋值(operator =)为一个derived class object 时,derived object的base 部分会被切割(sliced)以塞入base type内存中,derived type将没有留下任何蛛丝马迹(即:base class object 的vptr不会被derived class object的vptr替换)
代码语言:javascript复制#include<iostream>
using namespace std;
class ZooAnimal{
public:
ZooAnimal(int l):loc(l)
{
}
virtual void print()
{
cout<<"ZooAnimal";
}
private:
int loc;
};
class Bear : public ZooAnimal{
public:
Bear(int c, int l):ZooAnimal(l), cell(c)
{
}
private:
void print()
{
cout<<"Bear";
}
private:
int cell;
};
int main()
{
Bear b(1, 2);
ZooAnimal z = b;
z.print();
}
以上代码对应的汇编如下(g -S -m32 p27.cc):
代码语言:javascript复制_ZN9ZooAnimalC2ERKS_: //ZooAnimal默认copy ctor
.LFB1031:
.cfi_startproc
pushl �p
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, �p
.cfi_def_cfa_register 5
movl $_ZTV9ZooAnimal 8, �x //edx=ZooAnimal.vptr
movl 8(�p), �x //eax=[ebp 8],即eax=z.this
movl �x, (�x) //设置z的vptr
movl 12(�p), �x //eax=b.this
movl 4(�x), �x //edx = b.loc
movl 8(�p), �x //eax=z.this
movl �x, 4(�x) //z.loc = b.loc
nop
popl �p
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
代码语言:javascript复制main:
.LFB1029:
.cfi_startproc
leal 4(%esp), �x
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(�x)
pushl �p
.cfi_escape 0x10,0x5,0x2,0x75,0
movl %esp, �p
pushl �x
.cfi_escape 0xf,0x3,0x75,0x7c,0x6
subl $36, %esp
movl %gs:20, �x
movl �x, -12(�p)
xorl �x, �x
subl $4, %esp
pushl $2
pushl $1
leal -24(�p), �x //eax=ebp-24, b对象首地址
pushl �x //b的首地址压栈,即b.this压栈
call _ZN4BearC1Eii //Bear::Bear(b.this, 1, 2)
addl $16, %esp
subl $8, %esp
leal -24(�p), �x //eax = ebps-24, 即eax=b.this
pushl �x //b.this压栈
leal -32(�p), �x //eax=ebp-32,即eax=z.this
pushl �x //z.this压栈
call _ZN9ZooAnimalC1ERKS_ //ZooAnimal::ZooAnimal(ZooAnimal const&)
addl $16, %esp
subl $12, %esp
leal -32(�p), �x //eax=z.this
pushl �x //z.this压栈
call _ZN9ZooAnimal5printEv //ZooAnimal::print()
addl $16, %esp
movl $0, �x
movl -12(�p), �x
xorl %gs:20, �x
je .L8
call __stack_chk_fail
.L8:
movl -4(�p), �x
.cfi_def_cfa 1, 0
leave
.cfi_restore 5
leal -4(�x), %esp
.cfi_def_cfa 4, 4
ret
.cfi_endproc
2.图示
3.参考
《深度探索C 对象模型》