Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Virtual table/dispatch table

From what I know of CPP, each class has its own vtable.

However this wikipedia link mentions:

An object's dispatch table will contain the addresses of the object's dynamically bound methods. Method calls are performed by fetching the method's address from the object's dispatch table. The dispatch table is the same for all objects belonging to the same class, and is therefore typically shared between them.

Can someone please shed some light.

Thanks !

like image 354
codeObserver Avatar asked Jul 07 '11 06:07

codeObserver


People also ask

What are virtual tables in C++?

V-tables (or virtual tables) are how most C++ implementations do polymorphism. For each concrete implementation of a class, there is a table of function pointers to all the virtual methods. A pointer to this table (called the virtual table) exists as a data member in all the objects.

What is V table and how it is used?

Whenever there is a virtual function call, the v-table is used to resolve to the function address. An object of the class that contains one or more virtual functions contains a virtual pointer called the vptr at the very beginning of the object in the memory.

How does the vtable work?

For every class that contains virtual functions, the compiler constructs a virtual table, a.k.a vtable. The vtable contains an entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function definition callable by the class is stored in the vtable.

What is vtable and VPTR?

# Vtable is created by compiler at compile time. # VPTR is a hidden pointer created by compiler implicitly. # If base class pointer pointing to a function which is not available in base class then it will generate error over there. # Memory of Vtable and VPTR gets allocated inside the process address space.


2 Answers

It's sometimes easier to understand with an example:

class PureVirtual {
   public:
       virtual void methodA() = 0;
       virtual void methodB() = 0;
};

class Base : public PureVirtual {
   public:
        virtual void methodA();
        void methodC();
   private:
        int x;
 };

 class Derived : public Base {
    public:
         virtual void methodB();
    private:
         int y;
 };

So, given an object of type Derived it might look like:

                         ------------
 Known offset for vtable |  0xblah  | -------> [Vtable for type "Derived"]
                         ------------
 Known offset for x      |  3       |
                         ------------
 Known offset for y      |  2       |
                         ------------

With the Vtable for type "Derived" looking something like:

                            ------------
 Known offset for "methodA" | 0xblah1   | ------> methodA from Base
                            -------------
 Known offset for "methodB" | 0xblah2   | ------> methodB from Derived
                            -------------

Note that since "methodC" was not virtual, it is not in the vtable at all. Also note that all instances of class Derived will have a vtable pointer to the same, shared vtable object (since they have the same type).

Though the implementations for C++ and Java are slightly different, the ideas are not incompatible. The key difference, from a conceptual standpoint, is that Java methods are "virtual" unless declared "final". In C++ the keyword "virtual" must be given explicitly for the function to be in the vtable. Anything not in vtable will be dispatched using the compile-time types rather than the runtime type of the object.

like image 91
Michael Aaron Safyan Avatar answered Sep 27 '22 22:09

Michael Aaron Safyan


Yes, virtual methods are treated differently by the compiler and the runtime.

Java : All methods in java are virtual by default. That means that any method can be overridden when used in inheritance, unless that method is declared as final or static.

From the VM Specification,

The Java virtual machine does not mandate any particular internal structure for objects. The book mark there states: In some of Sun's implementations of the Java virtual machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the heap for the object data.


C++ :

Whenever a class member function is declared as virtual, the compiler creates a virtual table in memory which contains all function pointers that are declared as virtual in that class. This enables run time polymorphism (i.e. finding out the desired function at run time). Virtual function tables also have an additional pointer in the object to the vtable. As this additional pointer and the vtable increases the size of the object, a class designer needs to be judicious about declaring functions virtual.

The sequence of events upon calling a method on the base object pointer is :

  • Get vtable pointer (this vtable pointer points to the beginning of the vtable).
  • Get the function pointers in the vtable using offset.

Invoke the function indirectly through the vtable pointer.

like image 33
Saurabh Gokhale Avatar answered Sep 27 '22 22:09

Saurabh Gokhale