Analysis of C++ virtual function implementation mechanism

  • 2020-04-02 02:35:23
  • OfStack

In this paper, the implementation mechanism of C++ virtual functions is analyzed in depth, as follows:

1. In short, virtual functions are implemented through virtual function tables . So, what is a table of virtual functions?
In fact, if a class contains virtual functions, the system assigns a pointer member to the class to point to a VTBL table, where each entry points to the address of a virtual function, which is implemented as an array of function Pointers.

Here's an example:


class Parent
{
public:
 virtual void foo1() { }
 virtual void foo1() { }
 void foo1();
};

class Child1
{
public:
 void foo1() { }
 void foo3();
};

class Child2
{
public:
 void foo1() {}
 void foo2() {}
 void foo3();
};

The table of virtual functions (VTBL) for each class is listed below.
Address of the Parent class VTBL: Parent::foo1(), Parent::foo1().
Address of VTBL: Child1::foo1() of the Child1 class, Parent::foo1().
Address of VTBL: Child1::foo1() of the Child2 class, Child2::foo1().

2. As can be seen, Virtual function table has inheritance and polymorphism . Each derived class's VTBL inherits the VTBL of its base classes, and if the base class VTBL contains an item, the derived class's VTBL will also contain the same item, but the two items may have different values. If the derived class overrides the corresponding virtual function, the pointer to the derived class VTBL first points to the overloaded virtual function, and if not, the value of the base class is used.

3, In the memory layout of a class object, the VTBL pointer to the class is first followed by the object data . When a virtual function is called through an object pointer, the code generated by the compiler gets a VTBL pointer to the object class and then calls the corresponding item in VTBL. In the case of a call through an object pointer, it is not possible to determine at compile time whether the pointer points to a base class object or a derived class object, or to which derived class object. But by the time the call statement is executed at run time, it is established that the compiled calling code can get the right VTBL for the specific object, call the right virtual function, and achieve polymorphism.

4. Analyze the ideas here:
The essence of the problem is, how do you make a transition between an object pointer that makes a virtual function call that lacks more information at compile time and enough information at run time, but is no longer bound?
The information required for the binding is recorded in a generic data structure that can be associated with an object pointer, which is used only for abstract binding at compile time, and for real binding at run time. This data structure is VTBL. As you can see, implementing the abstraction and polymorphism required by the user requires post-binding, which the compiler does.


Related articles: