This paper mainly makes a simple summary of C + + object model. This paper discusses the memory layout of C + + objects in the following situations.
1) single general inheritance
2) single virtual inheritance
3) multiple inheritance
4) repeat multiple inheritance
5) virtual Multiple inheritance of diamond type
Virtual functions
Let's briefly introduce the mechanism of virtual function. The main function of virtual function is to realize the mechanism of polymorphism. For polymorphism, in short, a pointer to the parent type points to an instance of its child class, and then invokes the member function of the actual subclass through a pointer to the parent class. So that the pointer of the parent class has "multiple forms", which is a generic technique.
All know that virtual functions are implemented by a virtual table, which is primarily a list of address lists of virtual functions of a class. In an instance of a class with virtual functions, the table is allocated in the memory of the instance, which is like a map pointing to the function that should actually be called. To ensure the highest performance for a virtual function table, the C + + compiler generally guarantees that pointers to virtual function tables are placed at the very front of the object instance. This means that we can get this virtual function table through the address of the object instance, thus traversing all of the function pointers and invoking them.
A practical example is given below.
1 classBase {2 Public:3 Virtual voidF () {cout <<"Base::f"<<Endl;}4 Virtual voidG () {cout <<"base::g"<<Endl;}5 Virtual voidH () {cout <<"base::h"<<Endl;}6 7};
We can get the virtual function table through the example of base, using the following code:
1typedefvoid(*fun) (void);2 3 Base B;4 5Fun Pfun =NULL;6 7cout <<"address of virtual function table pointer:"<< (int*) (&B) <<Endl;8cout <<"virtual function table-First function address:"<< (int*)*(int*) (&B) <<Endl;9 Ten //Invoke The first virtual function OnePfun = (Fun) * ((int*)*(int*) (&b)); APfun ();
The results of the operation are as follows:
We forcibly convert the &b to int *, get the address of the virtual function table pointer, and then fetch the address of the first virtual function again, that is, Base::f (). Similarly, if we want to invoke Base::g () and base::h (), we can use the following code:
1 (Fun) * ((int*) * (int*) (&b) +0); // base::f () 2 (Fun) * ((int*) * (int*) (&B) +1); // base::g () 3 (Fun) * ((int*) * (int*) (&B) +2); // base::h ()
can help understand:
Note: In the above figure, there is a point at the end of the virtual function table, which is the end point of the virtual function table. This value is different under different compilers. In win8.1+vs2013, this value is null. In Ubuntu 14.04+gcc4.8.2, if this value is 1, there is also the next virtual function table (multiple inheritance), and if the value is 0, it is the last virtual function table.
(not to be continued)
C + + object model