1. class c010 {virtual void Foo () {};}; // sizeof = 4 with only one virtual function output: the size of c010 is 4The detail of c010 is 50 D0 46 00 when a class has a virtual function, the compiler will generate a virtual function table for this class, insert a pointer to the virtual function table in each of its objects. Generally, this pointer is inserted at the starting position of the object. The so-called virtual function table is actually a pointer array, in which the Pointer Points to the real function start address. In this test output, the virtual table entry address is 0x0046d050. 2. class c011 {PRIVATE: Char C; int I; public: c011 () {c = 0x01; I = 7 ;}; virtual void Foo () {};}; // sizeof = 12 the output result is: the size of c011 is 12The detail of c011 is 50 D0 46 00 01 CC 07 00 00 00 if you declare two c011 class instance objects obj1 and obj2, print their information as follows: obj1: objadr: 0012ff74 vpadr: 0012ff74 vtadr: 0046d064 vtival (0): large: objadr: 0012ff68 vpadr: 0012ff68 vtadr: Large vtival (0): 00401249 (Note: First column) Object Name, the second column (objadr) is the object's memory address, the third column (vpadr) is the virtual table pointer address, and the fourth column (vtadr) is the virtual table address, the Fifth Column (vtival (N) is the value of the entry in the virtual table, and N is the index of the entry, starting from 0. The object address is different. The virtual table pointer (vpadr) is located at the starting position of the object, so its address is the same as that of the object. The virtual table pointer of the two objects points to the same virtual table, so the value of (vtadr) is the same, and the value of the first object (vtival (0) in the virtual table is of course the same. 3. class c012: Public c011 {}; // sizeof = 12 the output result is: the size of c011 is 12The detail of c011 is 58 D0 46 00 01 CC 07 00 00 00 00the size of c012 is 12The detail of c012 is 5C D0 46 00 01 CC 07 00 00 00 each class maintains its own virtual table, therefore, the virtual table entry addresses of c011 and c012 are different. However, the content stored in c011 is completely inherited. Class c013: Public c011 {private: Short s; public: c013 () {S = 25 ;};/// sizeof = 16 the output result is: the size of c011 is 12The detail of c011 is 58 D0 46 00 01 CC 07 00 00 00 00the size of c013 is 16the detail of c013 is 5C D0 46 00 01 CC 07 00 00 00 19 00 CC if two instance objects of c011 and c013 are declared, print their information as follows: obj1: objadr: 0012ff74 vpadr: 0012ff74 vtadr: 0046d064 vtival (0): 004011f4obj3: objadr: 0012ff64 vpadr: 0012ff64 v Tadr: 0046d068 vtival (0): 004011f4 although their virtual tables are different, the entry address of function Foo stored in Table 0 is the same, this is because the virtual functions of the base class are not overwritten in the derived class, so the implementation of the base class will still be called. After some common members are added to the derived class, except that the virtual table Pointer Points to the virtual table of the derived class, the other rules are no different from those of the normal class. 4. class c014 {char C; public: c014 () {c = 0x77 ;}; virtual vfun1 () {printf ("base func1.") ;}; virtual vfun2 () {};}; // sizeof = 8 class c015: Public c014 {int I; public: c015 () {I = 1024 ;}; virtual vfun1 () {printf ("derived func1 .");};}; // sizeof = 12 indicates two virtual functions vfun1 and vfun2 in the base class c014, and overwrites vfun1 In the derived class c015. Output result: the size of c014 is 8The detail of c014 is A0 F0 46 00 77 CC ccthe size of c015 is 12The detail of c015 is BC F0 46 00 77 CC 00 04 00 00obj4: objadr: 0012ff5c vpadr: 0012ff5c vtadr: 0046f0a0 vtival (0): pushed: objadr: Pushed vpadr: Pushed vtadr: Pushed vtival (1): pushed: objadr: Pushed vpadr: 0012ff50 vtadr: 0046f0bc vtival (0): 0040da-2obj5: objadr: 0012ff50 vpadr: 0012ff50 Vtadr: 0046f0bc vtival (1): 00401307 virtual pointers of base classes and derived classes point to their respective virtual tables. Table 0th in virtual tables points to different function implementations, this is because the derived class is overwritten. The contents of table No. 1st are the same. The derived class inherits the implementation of the base class. If a new virtual member function vitrual void vfun3 () {}; is added to the implementation of the derived class c015 in the preceding example, the new output result is: the size of c014 is 8The detail of c014 is A0 F0 46 00 77 CC ccthe size of c015 is 12The detail of c015 is BC F0 46 00 77 CC 00 04 00 00obj4: objadr: 0012ff5c vpadr: 0012ff5c vtadr: 0046f0a0 vtival (0): pushed: objadr: Pushed vpadr: Pushed vtadr: Pushed vtival (1): pushed: objadr: Pushed vpadr: 0012ff50 vtadr: 0046f0bc Vtival (0): Failed: objadr: 0012ff50 vpadr: 0012ff50 vtadr: 0046f0bc vtival (1): Failed: objadr: 0012ff50 vpadr: 0012ff50 vtadr: 0046f0bc vtival (2 ): 00401267 there is still only one virtual pointer in the derived class, but a new table item is added, pointing to the entry address of vfun3. 5. multi-inheritance class base1 {public: base1 (): C (0x01) {}virtual void foo1 () {c = 0x02 ;}char C ;}; class base2 {public: base2 (): C (0x02) {} virtual void foo2 () {}char C ;}; class derived: Public base1, public base2 {}; the output result is: the size of derived is 16the detail of derived is 70 D0 46 00 01 CC 6C D0 46 00 02 CC is still the same as that of common classes, the derived class derived first inherits the content of the left base class base1, followed by the content of base2. Therefore, a derived class has two virtual pointers pointing to two different virtual tables. This object layout makes it easier to adjust the pointer when processing dynamic conversions of types. Override the virtual function and add the new virtual function's derived class: struct derived_manip: Public base1, public base2 {public: void foo2 () {printf ("Hello world! ") ;}; Virtual int foo3 () {return 5 ;};/// sizeof = 16 the output result is: the size of derived_manip is 16the detail of derived_manip is B8 F0 46 00 01 CC B4 F0 46 00 02 CC there are still only two virtual pointers in the derived class pointing to two different virtual tables. The newly added foo3 is placed at the end of the virtual table pointed to by the first virtual pointer. D: objadr: 0012ff60 vpadr: 0012ff60 vtadr: Drawing vtival (0): Drawing: objadr: 0012ff60 vpadr: 0012ff60 vtadr: Drawing vtival (1): Drawing: objadr: 0012ff60 ADR vp: 0012ff68 vtadr: 0046f0b4 vtival (0): 0040114f 6. multi-layer inheritance class level_1 {char C1; public: level_1 () {C1 = 0x00 ;}; virtual void set1 () {};}; class level_2: public level_1 {char C2; public: level_2 () {C2 = 0x01 ;}; virtual void set2 () {};}; class level_3: Public level_2 {char C3; public: level_3 () {C3 = 0x02 ;}; virtual void set3 () {};}; the output result is: the size of level_3 is 16the detail of level_3 is 54 D0 46 00 00 CC 01 CC 02 CC multi-layer inheritance only saves the only one inherited from the top-level base class virtual pointer. This is also the inevitable result of following the inheritance rules. 7. multi-level and multi-level inheritance class L1 {char C1; public: L1 () {C1 = 0x00 ;}; virtual void set1 () {};}; class L2 {char C2; public: L2 () {C2 = 0x01 ;}; virtual void set2 () {};}; class L3: Public L1, public L2 {char C3; public: l3 () {C3 = 0x02 ;}; virtual void set3 () {};}; class L4 {char C4; public: L4 () {C4 = 0x03 ;}; virtual void set4 () {};}; class L5: Public L3, public L4 {char C5; public: l5 () {C5 = 0x04 ;}; virtual void set5 () {};}; output end Result: the size of L5 is 32The detail of L5 is 54 D0 46 00 00 CC 50 D0 46 00 01 CC 02 CC cc4c D0 46 00 03 03 CC 04 CC ccobj: objadr: 0012ff60 vpadr: 0012ff60 vtadr: 0046d060 vtival (2): The entry address of the virtual function set5 added in 00401118l5 is saved as the end of the first virtual table. The phenomenon follows the inheritance rules.