#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_1()
         {
             printf("Base2 function_1...\n");
         }
        virtual void function_3()
         {
             printf("Base2 function_3...\n");
         }
     
 };
 class Sub :  Base2
 {
     public:
         virtual void function_5()
         {
             printf("Sub function_5...\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 bfd5ccf0.
     sub virtual table address is:80489f8
     Base2 function_1...
     Base1 function_2...
     Base2 function_3...
     Sub function_5...
  */
#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\n", sizeof(class Sub));    // 4。 直接继承一个父类,所以只有一个虚函数表
  8048715:    c7 44 24 04 04 00 00     movl   $0x4,0x4(%esp)
  804871c:    00
  804871d:    c7 04 24 a6 89 04 08     movl   $0x80489a6,(%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 b1 89 04 08     movl   $0x80489b1,(%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 c8 89 04 08     movl   $0x80489c8,(%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










