C++2.0 after the full support virtual function and virtual inheritance, the introduction of these two features for C + + enhanced a lot of features, but also introduced a lot of trouble. virtual function and virtual inheritance have what characteristics, today do not record, if you can understand how the compiler to implement virtual functions and virtual inheritance, they are in the memory space of the class is how to layout, but can have a deep understanding of C + +. This time spent some time to understand these things, make even, but finally some harvest, hey.
Look at a piece of code first
Class A
{
Virtual AA () {};
};
class b:public virtual A
{
char j[3]; // Add a variable to see where the vfptr in the class are placed
public:
virtual bb () {};
};
Class C:public Virtual B
{
char i[3];
Public:
Virtual cc () {};
};
This time not to give results, first analysis, or strengthen the impression.
1, for class A, because there is only one virtual function, then must have a corresponding virtual function table, to record the corresponding function entry address. At the same time in the memory space of Class A need to have a vfptr_a point to the table. sizeof (A) is also easy to determine, for 4.
2, for Class B, because Class B virtual basis of Class A, but also have their own virtual function. Then class B first has a vfptr_b, pointing to its own virtual function table. Also char j[3], do once alignment, the general size is 4. How can virtual inheritance be implemented? This is AH problem! I did not know before, fortunately, C + + Object model is introduced. The first thing to do is to point to its parent class by adding a virtual L-class pointer (vbptr_b_a), and then include all the contents of the parent class. It's a little complicated, but it's not hard to imagine. sizeof (B) = 4+4+4+4=16 (Vfptr_b, char j[3] do alignment, vbptr_b_a, and class A).
3, followed by Class C. Class C must first have a vfptr_c, then Char i[3], then Vbptr_c_b, then class B, so sizeof (c) =4+4+4+16=28 (Vfptr_c, char i[3] do alignment, Vbptr_c_a and Class B).
VC 6.0 wrote a program, the above several classes of the size of the print out, sure enough, the result is 4, 16, 28. HoHo's done! Is it really done? Perhaps through the above analysis, although each class specific memory layout is not clear, but the content should not be wrong. Hey, I really think so when I'm not tracking, but the result is ...
Memory layout of virtual inheritance in VC--Single inheritance
I drew a diagram that simply showed me the results of my follow-up.
Memory layout diagram of Virtual Foundation when single inheritance
Class A is too simple, no problem. The following conclusions can be drawn from the memory layout diagram of Class B.
1, Vf_ptr B placed in the first class, then if you want to take memcpy to complete the replication of the class is very dangerous, with a struct is not. Another day in-depth study of the difference between the struct and class, you can see the difference here.
2, Vbtbl_ptr_b, why not the vbptr_b_a I described earlier? Because this pointer is very different from what I had previously guessed. This pointer points to Class B's virtual Class table (well, I am the name of my own, it is not fine). Look at the VB table,vb table has two items, the first item is FFFFFFFC, the value of this item may not be meaningful, may be to ensure that the virtual class table is not empty. The second entry is 8, which looks like the shift of Class A in class B relative to the Vbtbl_ptr_b, which is an offset. Similar methods are introduced in C + + Object Model (P121) and can be seen.
The memory layout of Class C is more complex, but its memory layout also shows that I understand the content in Vbtbl_ptr_b, which is the virtual class table, is correct. However, it's worth noting that Class A in class B is moved to the front in the layout, although the whole size has not changed, but if you do such a operation C C; b *b;b=&c; How about the operation of B? At this point, the position of Class B can be assigned to B only from the virtual table of C. But it's a bit more complicated to build Class C, and the latter is very simple and efficient. The memory layout of Class A can be moved forward by considering the virtual inheritance order of C.
Conclusion
1, VC at compile time will put vfptr to the head of the class;
2, VC uses virtual table pointer (vbtbl_ptr) to determine the virtual class inherited by a class.
3, the VC will re-adjust the virtual inheritance of the parent class in the child class memory layout. (The specific rules are unclear)
4, VC in the Virtual class table in the first item is meaningless, may be to ensure that sizeof (virtual class table)!=0; The following content is the offset of the parent class relative to the virtual class table pointer in the subclass.
At present, virtual inheritance in the single inheritance of the memory layout is still relatively clear, but multiple inheritance? This is too bt, simple multiple inheritance has not been clear, and then a virtual inheritance, not only. When I'm interested, I'm looking for something to do.
http://blog.csdn.net/adcxf/article/details/2226915
Virtual inheritance of a single inherited memory layout (VC at compile time will put vfptr to the head of the class, which is exactly the same as Delphi)