Recently, I read the memory layout of objects with virtual inheritance levels in the inside C ++, and found that the implementations in different compilers are different. Therefore, I explored it myself. The result is as follows:
First, let's talk about the GCC compiler.
It is easy to implement. No matter whether it is virtual inheritance or not, GCC shares the virtual table pointer in the entire inheritance relationship. What is not shared is the pointer to the virtual base class.
Class {
Int;
Virtual ~ A (){}
};
Class B: virtual public {
Virtual ~ B (){}
Virtual void myfunb (){}
};
Class C: virtual public {
Virtual ~ C (){}
Virtual void myfunc (){}
};
Class D: Public B, public c {
Virtual ~ D (){}
Virtual void myfund (){}
};
AboveCodeSizeof (A) = 8, sizeof (B) = 12, sizeof (c) = 12, sizeof (d) = 16.
Explanation: int + virtual table pointer in. In B and C, because it is a virtual inheritance, the size is a + pointer to the virtual base class. Although B and C are added with their own virtual functions, however, the virtual table pointer is shared with the base class, so it does not have its own virtual table pointer. D Because B and C are virtual inheritance, d only contains a copy of, the size of D is equal to the pointer pointing to the virtual base class in A + B + the pointer pointing to the virtual base class in C.
If B and C are not virtual inheritance, but normal inheritance, the size of A, B, and C is 8 (no pointer pointing to the virtual base class ), because D is not a virtual inheritance, it contains two A copies with a size of 16. note that although the size of D is the same as that of virtual inheritance, the memory layout is different.
Then, let's take a look at the VC compiler.
VC's processing of virtual table pointers is more complex than GCC's. It determines whether to share virtual table pointers in the inheritance relationship based on whether virtual inheritance is used, the pointer to the virtual base class is not shared like GCC, and of course it cannot be shared.
The Code is the same as above.
The running result will be sizeof (A) = 8, sizeof (B) = 16, sizeof (c) = 16, sizeof (d) = 24.
Explanation: A still contains int + virtual table pointers. In B and C, the virtual table pointer is not shared because it is virtual inheritance. Because B and C have their own virtual functions, B and C Maintain a virtual table pointer respectively, it points to its own virtual function. (Note: The Compiler adds a virtual table pointer to the subclass only when the subclass has a new virtual function.) Therefore, B, the C size is a + your own virtual table pointer + pointer to the virtual base class. D Because B and C are virtual inheritance, d only contains a copy of A, and D is inherited from B and C, rather than virtual inheritance, therefore, you do not have your own virtual table pointer. The size of D is equal to the virtual table pointer of A + B + the virtual table pointer of C + the pointer of B to the virtual base class + the pointer of C to the virtual base class.
Similarly, if virtual inheritance is removed, the result will be the same as the GCC result. A, B, and C are both 8 and D is 16, because the VC compiler is not virtual inheritance, parent and Child classes share virtual table pointers.