Content #
#include <cstdio>
class A {
public:
int a;
virtual void foo() {
printf("In A\n");
}
};
class B : public A {
public:
int b;
virtual void foo() {
printf("In B\n");
}
};
int main() {
A* obj = new B();
obj->a = 1;
obj->foo();
return 0;
}
用objdump查看反汇编后的指令,关键部分如下:
mov -0x18(%rbp),%rax
movl $0x1,0x8(%rax) ;给a赋值
mov -0x18(%rbp),%rax
mov (%rax),%rax ;rax中内容为虚表地址
mov (%rax),%rax ;加载虚表指向的地址
mov -0x18(%rbp),%rdx
mov %rdx,%rdi ;传入this指针
callq *%rax
还可以注意到,给a赋值时,a的起始位置离(%rax)多了8个字节,这就是为虚表留下的位置。如果去掉virtual修饰符,那么,给a赋值时,应该从(%rax)开始。