Unveil the "mystery" of virtual tables in the C ++ class
The virtual table structure in the C ++ class is an important knowledge point in the C ++ object model. Here we will analyze the structure of the virtual table in the memory.
In C ++, if a class has a virtual function, there will be a virtual table pointer pointing to the corresponding virtual table. Generally, a class has only one virtual table, each virtual table has multiple "slots", and each slot stores the address of a virtual function. The content in the slot can be overwritten. If the subclass overrides the virtual function in the parent class, the data at the corresponding position in the slot is overwritten. The virtual table stores the virtual function address, whether it is public or private. The text description is not very good. The following figure shows an example of the virtual table structure:
It can be seen that the virtual table pointer actually points to the virtual table structure, which has many slots, each of which points to a virtual function. Then, let's take a look at how to test it with a program:
1 # include <iostream> 2 # include <cstdio> 3 4 using namespace std; 5 6 class Base {7 public: 8 virtual void test () {9 cout <"Base. text () "<endl; 10} 11 12 public: 13 int a; 14}; 15 16 class Derived: public Base {17 public: 18 virtual void test () {19 cout <"Derived. test () "<endl; 20} 21 22 public: 23 int B; 24}; 25 26 typedef void (* PFunc) (); 27 28 int main () {29 Derived derived; 30 PFunc ptest; // function pointer 31 32 // output address of derived and its member a/B 33 printf ("derived: % p \ n ", & derived); 34 printf ("derived. a: % p \ n ", & (derived. a); 35 printf ("derived. b: % p \ n ", & (derived. b); 36 37 // extract the test virtual function address 38 int * p = (int *) * (int *) (& derived); 39 ptest = (PFunc) * p; 40 ptest (); 41 42 return 0; 43}
Output result:
Note that the program is tested in Centos 7 64-bit system. The program extracts the test virtual function address and calls it. It finds that the call is actually the Derived. test function, which also shows the memory layout of the virtual table structure.
Interesting questions about virtual tables
When is a virtual table pointer assigned?
1 # include <iostream> 2 3 using namespace std; 4 5 class Base 6 {7 public: 8 Base () {9 cout <"Base ()" <endl; 10 show (); 11 int * p = & B; 12 cout <"Base: B:" <p <endl; 13 p = (int *) (char *) p-8); 14 cout <"Base: vptr:" <* p <endl; 15 // The virtual function address in the Base is 16 cout <"* Base: vptr:" <* (int *) * p <endl; 17 cout <endl; 18} 19 20 virtual void show () {21 cout <"Base: show ()" <endl; 22} 23 public: 24 int B; 25 }; 26 class Derived: public Base27 {28 public: 29 Derived () 30 {31 cout <"Derived ()" <endl; 32 show (); 33 int * p = & B; 34 cout <"Derived: B:" <p <endl; 35 p = (int *) (char *) p-8); 36 cout <"Derived: vptr:" <* p <endl; 37 // The virtual function address in Derived is 38 cout <"* Derived:: vptr: "<* (int *) * p <endl; 39 cout <endl; 40} 41 virtual void show () {42 cout <" Derived :: show () "<endl; 43} 44 private: 45 int d; 46}; 47 48 int main (int argc, char ** argv) 49 {50 Base base; 51 Derived derived; 52 53 return 0; 54}
Output result:
From the output result, we can conclude that during the construction of the subclass, the virtual table pointer will be assigned twice. The initialization is as follows:
Base Class static member-subclass static member-(set v_ptr/base class member variable)-base class constructor-(set v_ptr/subclass member variable)-subclass Constructor
Does the class destructor assign values to virtual table pointers?
In the destructor of the subclass, the virtual table pointer is set to point to the virtual function address in the parent class, in this way, the virtual function called in the destructor of the parent class actually calls the virtual function of the parent class, but this is generally not done. How to perform the test? According to the test code of the previous question, you can test it with a slight change.
Refer:
1. Have a deep understanding of the C ++ Object Model
2. in-depth exploration of the C ++ Object Model