#include <iostream>
#include <stdio.h>
class Base
{
public:
int x;
int y;
virtual void function_1()
{
printf("function_1...\n");
}
virtual void function_2()
{
printf("function_2...\n");
}
};
int main(int argc, char ** argv)
{
Base base;
Base *pb;
pb = &base;
printf("aaa %ld\n", sizeof(int)); //
printf("aaa %ld\n", sizeof(float)); //
printf("aaa %ld\n", sizeof(long)); //
printf("aaa %ld\n", sizeof(double)); //
printf("size %d\n", sizeof(class Base)); // 12, 有virtual函数就会多出4字节,多个virtual函数也是4字节。
pb->function_1();
pb->function_2();
}
#if 0
1.当在类里加virtual后多出4个字节,这4个字节在对象的首地址。
2.这4个字节本身是个地址,这个地址里面存的值才是要调用的函数地址。
3.这4个字节指向一个数组,这个数组里面存储的是当前这个对象所有的虚函数的地址。
int main(int argc, char ** argv)
{
8048670: 55 push %ebp
8048671: 89 e5 mov %esp,%ebp
8048673: 83 e4 f0 and $0xfffffff0,%esp
8048676: 83 ec 20 sub $0x20,%esp
Base base;
8048679: 8d 44 24 10 lea 0x10(%esp),%eax
804867d: 89 04 24 mov %eax,(%esp)
8048680: e8 cb 00 00 00 call 8048750 <_ZN4BaseC1Ev>
Base *pb;
pb = &base;
8048685: 8d 44 24 10 lea 0x10(%esp),%eax
8048689: 89 44 24 1c mov %eax,0x1c(%esp)
printf("size %d\n", sizeof(class Base)); // 12, 有virtual函数就会多出4字节,多个virtual函数也是4字节。
804868d: c7 44 24 04 0c 00 00 movl $0xc,0x4(%esp)
8048694: 00
8048695: c7 04 24 10 88 04 08 movl $0x8048810,(%esp)
804869c: e8 9f fe ff ff call 8048540 <printf@plt>
pb->function_1();
80486a1: 8b 44 24 1c mov 0x1c(%esp),%eax
80486a5: 8b 00 mov (%eax),%eax
80486a7: 8b 00 mov (%eax),%eax
80486a9: 8b 54 24 1c mov 0x1c(%esp),%edx
80486ad: 89 14 24 mov %edx,(%esp)
80486b0: ff d0 call *%eax
pb->function_2();
80486b2: 8b 44 24 1c mov 0x1c(%esp),%eax
80486b6: 8b 00 mov (%eax),%eax
80486b8: 83 c0 04 add $0x4,%eax
80486bb: 8b 00 mov (%eax),%eax
80486bd: 8b 54 24 1c mov 0x1c(%esp),%edx
80486c1: 89 14 24 mov %edx,(%esp)
80486c4: ff d0 call *%eax
}
80486c6: b8 00 00 00 00 mov $0x0,%eax
80486cb: c9 leave
80486cc: c3 ret
#endif

本文探讨了C++中虚函数如何影响类的内存布局。通过实例展示了类包含虚函数时,对象会多出4个字节用于存放虚函数表指针。这个指针指向一个包含所有虚函数地址的数组,从而实现动态绑定。此外,还展示了如何通过指针调用虚函数。
15万+

被折叠的 条评论
为什么被折叠?



