Microsoft Visual C ++ Virtual Multi-inheritance object model preliminary analysis
Dijunfeng 2004/8/25
I was inspired to read <inside the C ++ Object Module> a few days ago. Therefore, Microsoft Visual C ++ is analyzed in the case of Virtual Multi-inheritance. Correct your skills and learn from each other.
The following is an example:
Class {
Public:
A (): K (50 ){};
Virtual void fun () {cout <"FUNA" <Endl ;}
Int K;
};
Class B: virtual public {
Public:
Virtual void fun () {cout <"funb" <Endl ;}
Virtual void funb () {cout <"funbb" <Endl ;};
B (): I (70 ){};
Int I;
};
Class C: virtual public {
Public:
Virtual void fun () {cout <"func" <Endl ;}
C (): I (30 ){};
Int I;
};
Class D: Public B, public C
{
Public:
Virtual void fun () {cout <"fund" <Endl ;};
Virtual void Fund () {cout <"fundd" <Endl ;};
D (): D (100 ){};
Int D;
};
The memory structure of objects A, B, C, and D is analyzed as follows:
-----------------
| Vptr | ----> | A: Fun |
| ----------------
| K |
--------
Memory Structure of object
------------------
| Vptr (Class B) | -----> points to the list of non-overloaded virtual functions in B, for example, B: funb
------------------
| Offset; Value: 12 | ------> the pointer inserted by the compiler, which is the offset from the bottom vptr.
------------------
| I (B: I) |
------------------
| 0 (compiler inserted |
| The value of 4 bytes is 0. |
----------------------------
| Vptr | -----> | B: Fun |
----------------------------
| K (A: K) |
-------------------
Memory Structure of object B
------------------
| Vptr (Class C) | ---> points to the list of non-reloaded virtual functions in C. The access error occurs because C has no more than overloaded virtual functions.
------------------
| I (C: I) |
------------------
| 0 (compiler inserted |
| The value of 4 bytes is 0. |
----------------------------
| Vptr | -----> | C: Fun |
----------------------------
| K (A: K) |
-------------------
Memory Structure of Object C
------------------
| Vptr (Class D) | -----> List of non-heavy virtual functions in B and non-heavy virtual functions in D, for example, B: funb, D: Fund
------------------
| Offset; Value: 24 | ------> the pointer inserted by the compiler, which is the offset from the bottom vptr.
------------------
| I (B: I) |
------------------
| Vptr (Class C) | -----> points to the list of non-overloaded virtual functions in C. Access Error because C has no more than overloaded virtual functions
------------------
| I (C: I) |
------------------
| D (D: d) |
------------------
| 0 (compiler inserted |
| The value of 4 bytes is 0. |
----------------------------
| Vptr | -----> | D: Fun |
----------------------------
| K (A: K) |
-------------------
Memory Structure of object d
The following conclusions are drawn:
1. When dealing with Virtual Multi-inheritance, the first pointer at the top of the subclass (in example, B, c) is directed to the self-class virtual function table,
Does not include the list of virtual functions of the virtual inheritance base class. That is, virtual base-class virtual functions and sub-class virtual functions are processed separately.
2. When the subclass has a non-overloaded virtual function, the compiler inserts an offset pointer in the next four bytes,
The value is the offset from the bottom vptr pointer.
3. The vptr pointer under B c d automatically points to the list of overloaded virtual functions of the subclass through thunk technology.
4. the compiler inserts 4 bytes of 0 on the vptr pointer.
5. The first vptr of the memory structure diagram of D points to the virtual function list following the following rule: the virtual function table is the first parent class.
(Example: B) List of merged non-overloaded virtual functions and non-overloaded virtual functions in D. If the first parent class (for example, B)
Is the combination of non-overloaded virtual functions and non-overloaded virtual functions of D in the second parent class (for example, c ).
.
Pay test function: test other cases with slight modification.
Typedef void (* Fun) (void );
Int main (){
D objclass;
D;
Cout <sizeof (a) <Endl;
Cout <sizeof (B) <Endl;
Cout <sizeof (c) <Endl;
Cout <sizeof (d) <Endl;
Cout <"Address of virtual Pointer" <(& objclass + 0) <Endl;
Cout <"value at virtual pointer I. e. Address of virtual table"
<(Int *) * (int *) (& objclass + 0) <Endl;
Cout <"value at first entry of virtual table"
<(Int *) * (int *) (& objclass + 0) <Endl;
Cout <Endl <"executing virtual function" <Endl;
Fun pfun = (fun) (* (int *) (& objclass + 0) + 0 ));
Pfun ();
Cout <"Address of virtual Pointer" <(int *) (char *) & D + 28) <Endl;
Cout <"value at virtual pointer I. e. Address of virtual table"
<(Int *) * (int *) (char *) & D + 28) <Endl;
Cout <"value at first entry of virtual table"
<(Int *) * (int *) (char *) & D + 28) <Endl;
Cout <Endl <"executing virtual function" <Endl;
Fun pfun2 = (fun) (* (int *) (char *) & D + 28) + 0 ));
Pfun2 ();
Return 0;
}