Search code examples
c++virtualvtable

C++ , Why Base class needs a VTable


From my understanding a VTable is necessary to call the most derived version of function. It will have entries about the most derived version of function ... My doubt is why we need to have a VTable for the base class. Since making calls with base object will always need to call the base class functions.


Solution

  • Since R Shau didn't like my edit, I provide my answer highly based on his.

    VTable is a way to deal with polymorphism. While VTable is a technique widely used by C++ compilers, they are free to provide any other solution.

    When a base class has one or more virtual member functions, the base class constructor assigns the VTable to an object.

    The base class constructor has no way of knowing whether the real object being constructed is a base class object or a derived class object, so base object must keep pointer to point to valid VTable.

    Example:

    struct Base
    {
        Base() {} 
    
        virtual void m() {}
    
        virtual ~Base() {}
    };
    
    struct Derived : public Base
    {
        Derived() : Base() {}
    
        void m() override {}
    
        ~Derived() override {}
    };
    
    void foo()
    {
        Base b;
        Derived d;
    
        Base * bPtr;
    }
    

    bPtr may point to Base

        bPtr = & b;
        bPtr->m();
    

    or Derived

        bPtr = & d;
        bPtr->m();
    

    Since bPtr is of type Base *, how to perform polymorphic call bPtr->m(), which should result in calling Base::m() if bPtr points to b and Derived::m() if bPtr points to d? Answer: look up for the address of m() method in VTable.

    What happens when resolving bPtr->m() is something like that:

       bPtr pointing to Base object
       bPtr-> vtable_pointer -> VTable of Base -> m() -> points to address of Base::m()
       
       bPtr pointing to Derived object
       bPtr-> vtable_pointer -> VTable of Derived -> m() -> points to address of Derived::m()
    

    So, without a VTable in base class, polymorphic calls could not be performed because at runtime it is not known if object pointed by bPtr is really a base class object or derived class object.