#include
#include <stdio.h>
/*
* 多重继承有函数覆盖
*/
class Base1
{
public:
virtual void function_1()
{
printf("Base1 function_1… ");
}
virtual void function_2()
{
printf("Base1 function_2… ");
}
};
class Base2 : public Base1
{
public:
virtual void function_3()
{
printf("Base2 function_3… ");
}
};
class Sub : Base2
{
public:
virtual void function_1()
{
printf("Sub function_1… ");
}
virtual void function_3()
{
printf("Sub function_3… ");
}
};
int main(int argc, char ** argv)
{
Sub sub;
printf("size = %d ", sizeof(class Sub)); // 4。 直接继承一个父类,所以只有一个虚函数表
printf("sub address is %x. ", &sub); // this 指针,是堆栈里面的地址。虚表的地址不是this指针,是this指针的前四个字节。
/* 对象的前4字节是第一个Base1的虚表 */
printf("sub virtual table address is:%x ", *(int*)&sub);
typedef void(*pfunction)(void);
pfunction pf;
for (int i = 0; i < 6; i++) {
int temp = *((int*)(*(int*)&sub) + i);
if (temp == 0) {
break;
}
pf = (pfunction)temp;
pf();
}
return 0;
}
/*
sub address is bfb701f0.
sub virtual table address is:80489f0
Sub function_1…
Base1 function_2…
Sub function_3…
*/
#if 0
int main(int argc, char ** argv)
{
8048700: 55 push %ebp
8048701: 89 e5 mov %esp,%ebp
8048703: 83 e4 f0 and $0xfffffff0,%esp
8048706: 83 ec 20 sub $0x20,%esp
Sub sub;
8048709: 8d 44 24 10 lea 0x10(%esp),%eax
804870d: 89 04 24 mov %eax,(%esp)
8048710: e8 75 01 00 00 call 804888a <_ZN3SubC1Ev>
printf("size = %d ", sizeof(class Sub)); // 4。 直接继承一个父类,所以只有一个虚函数表
8048715: c7 44 24 04 04 00 00 movl $0x4,0x4(%esp)
804871c: 00
804871d: c7 04 24 a4 89 04 08 movl $0x80489a4,(%esp)
8048724: e8 a7 fe ff ff call 80485d0 printf@plt
printf("sub address is %x. ", &sub); // this 指针,是堆栈里面的地址。虚表的地址不是this指针,是this指针的前四个字节。
8048729: 8d 44 24 10 lea 0x10(%esp),%eax
804872d: 89 44 24 04 mov %eax,0x4(%esp)
8048731: c7 04 24 af 89 04 08 movl $0x80489af,(%esp)
8048738: e8 93 fe ff ff call 80485d0 printf@plt
/* 对象的前4字节是第一个Base1的虚表 */
printf("sub virtual table address is:%x ", *(int*)&sub);
804873d: 8d 44 24 10 lea 0x10(%esp),%eax
8048741: 8b 00 mov (%eax),%eax
8048743: 89 44 24 04 mov %eax,0x4(%esp)
8048747: c7 04 24 c4 89 04 08 movl $0x80489c4,(%esp)
804874e: e8 7d fe ff ff call 80485d0 printf@plt
typedef void(*pfunction)(void);
pfunction pf;
for (int i = 0; i < 6; i++) {
8048753: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp)
804875a: 00
804875b: eb 35 jmp 8048792 <main+0x92>
int temp = *((int*)(*(int*)&sub) + i);
804875d: 8b 44 24 1c mov 0x1c(%esp),%eax
8048761: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx
8048768: 8d 44 24 10 lea 0x10(%esp),%eax
804876c: 8b 00 mov (%eax),%eax
804876e: 01 d0 add %edx,%eax
8048770: 8b 00 mov (%eax),%eax
8048772: 89 44 24 18 mov %eax,0x18(%esp)
if (temp == 0) {
8048776: 83 7c 24 18 00 cmpl $0x0,0x18(%esp)
804877b: 75 02 jne 804877f <main+0x7f>
break;
804877d: eb 1a jmp 8048799 <main+0x99>
}
pf = (pfunction)temp;
804877f: 8b 44 24 18 mov 0x18(%esp),%eax
8048783: 89 44 24 14 mov %eax,0x14(%esp)
pf();
8048787: 8b 44 24 14 mov 0x14(%esp),%eax
804878b: ff d0 call *%eax
typedef void(*pfunction)(void);
pfunction pf;
for (int i = 0; i < 6; i++) {
804878d: 83 44 24 1c 01 addl $0x1,0x1c(%esp)
8048792: 83 7c 24 1c 05 cmpl $0x5,0x1c(%esp)
8048797: 7e c4 jle 804875d <main+0x5d>
pf = (pfunction)temp;
pf();
}
return 0;
8048799: b8 00 00 00 00 mov $0x0,%eax
}
804879e: c9 leave
804879f: c3 ret
#endif