#include <iostream> #include <stdio.h>
/* ?* 多重继承无函数覆盖 ?*/
class Base1 { ?? ?public: ?? ??? ?virtual void function_1() ?? ??? ?{ ?? ??? ??? ?printf("Base1 function_1...\n"); ?? ??? ?}
?? ??? ?virtual void function_2() ?? ??? ?{ ?? ??? ??? ?printf("Base1 function_2...\n"); ?? ??? ?} ?? ? };
class Base2 : public Base1 { ?? ?public: ?? ??? ?virtual void function_3() ?? ??? ?{ ?? ??? ??? ?printf("Base2 function_3...\n"); ?? ??? ?}
?? ??? ?virtual void function_4() ?? ??? ?{ ?? ??? ??? ?printf("Base2 function_4...\n"); ?? ??? ?} ?? ? };
class Sub :? Base2 { ?? ?public: ?? ??? ?virtual void function_5() ?? ??? ?{ ?? ??? ??? ?printf("Sub function_5...\n"); ?? ??? ?}
?? ??? ?virtual void function_6() ?? ??? ?{ ?? ??? ??? ?printf("Sub function_6...\n"); ?? ??? ?} };
int main(int argc, char ** argv) { ?? ?Sub sub;
?? ?printf("size = %d\n", sizeof(class Sub));?? ?// 4。 直接继承一个父类,所以只有一个虚函数表
?? ?printf("sub address is %x.\n", &sub);?? ??? ?// this 指针,是堆栈里面的地址。虚表的地址不是this指针,是this指针的前四个字节。
?? ?/* 对象的前4字节是第一个Base1的虚表 */ ?? ?printf("sub virtual table address is:%x\n", *(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 bfa78630. ?? ?sub virtual table address is:8048a48 ?? ?Base1 function_1... ?? ?Base1 function_2... ?? ?Base2 function_3... ?? ?Base2 function_4... ?? ?Sub function_5... ?? ?Sub function_6... ?*/
#if 0
1.覆盖的是哪个在哪个虚表里;
sub对象
?? ?---------------?? ??? ??? ?----------------- ?? ?| 0x123245??? |?? ?--------->?? ??? ?| 0x123456?? ?|?? ?Base1:function_1 ?? ?---------------?? ??? ??? ?----------------- ?? ?| ....??????? |?? ??? ??? ?| 0x123457?? ?|?? ?Base1:function_2 ?? ?---------------?? ??? ??? ?----------------- ?? ?| ....?? ?????? |?? ??? ??? ?| 0x123458?? ?|?? ?Base2:function_3 ?? ?---------------?? ??? ??? ?----------------- ?? ?| ....??????? |?? ??? ??? ?| 0x123457?? ?|?? ?Base2:function_4 ?? ?---------------?? ??? ??? ?----------------- ?? ?| ....?? ?????? |?? ??? ??? ?| 0x123457?? ?|?? ?Sub:function_5 ?? ?---------------?? ??? ??? ?----------------- ?? ?| 其它成员???? |?? ??? ??? ?| 0x123457?? ?|?? ?Sub:function_6 ?? ?---------------?? ??? ??? ?----------------- ?? ?| ....?? ?????? |?? ??? ??? ?| 0x000000?? ?| ?? ?---------------?? ??? ??? ?-----------------
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 89 01 00 00????? ??? ?call?? 804889e <_ZN3SubC1Ev>
?? ?printf("size = %d\n", sizeof(class Sub));?? ?// 4。 直接继承一个父类,所以只有一个虚函数表 ?8048715:?? ?c7 44 24 04 04 00 00 ?? ?movl?? $0x4,0x4(%esp) ?804871c:?? ?00 ?804871d:?? ?c7 04 24 e0 89 04 08 ?? ?movl?? $0x80489e0,(%esp) ?8048724:?? ?e8 a7 fe ff ff????? ??? ?call?? 80485d0 <printf@plt>
?? ?printf("sub address is %x.\n", &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 eb 89 04 08 ?? ?movl?? $0x80489eb,(%esp) ?8048738:?? ?e8 93 fe ff ff????? ??? ?call?? 80485d0 <printf@plt>
?? ?/* 对象的前4字节是第一个Base1的虚表 */ ?? ?printf("sub virtual table address is:%x\n", *(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 00 8a 04 08 ?? ?movl?? $0x8048a00,(%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
|