Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the structure of virtual tables in C++?

Tags:

c++

vtable


For Example I have two "intefaces" and class type:

class IPlugin
{
  public:
    virtual void Load(void) = 0;
    virtual void Free(void) = 0;
};

class IFoo
{
  public:
    virtual void Foo(void) = 0;
};


class Tester: public IPlugin, public IFoo
{
   public:
           Tester() {};
          ~Tester() {};

           virtual void Load()
           {
              // Some code here
           }

           virtual void Free()
           {
              // Some code here
           }

           virtual void Foo(void)
           {
              // Some code here
           }
 };

What structure vtab actually has for instance of type Tester? And how would be dynamic_cast operator act ( I mean how dynamic_cast operator would scan vtab for valid reference type convertion) in expression:

Tester* t = new Tester();
IPlugin* plg = dynamic_cast<IPlugin*>(t);
IFoo* f = dynamic_cast<IFoo*>(plg);  

Thanks in advance!

like image 340
Anton Semenov Avatar asked May 03 '11 10:05

Anton Semenov


People also ask

What is virtual table in C?

The virtual table is a lookup table of functions used to resolve function calls in a dynamic/late binding manner. The virtual table sometimes goes by other names, such as “vtable”, “virtual function table”, “virtual method table”, or “dispatch table”.

Which are virtual tables?

A virtual table is a set of columns that have specific names and data types. These columns describe the format of data that flows into and out of an operator. Each operator port in a data flow operator has a virtual table that defines the structure of the data coming into or leaving that port.

What is the type of VPTR?

It has no type. It's an implementation detail unspecified by the standard; it is not part of the language.

What is the use of virtual table?

A virtual table is an object that presents an SQL table interface but which is not stored in the database file, at least not directly. The virtual table mechanism is a feature of SQLite that allows SQLite to access and manipulate resources other than bits in the database file using the powerful SQL query language.


4 Answers

Virtual tables in C++ is an implementation detail. One possible implementation is shown on the diagram below.

Virtual table diagram

Two instances of the class (A and B) exists. Each instance has two vtbl pointers and the vtbl contains pointers to actual code.

In your example there is no instance data, but I have for illustrative purposes assumed that each class contains some instance data.

When a pointer to Tester is cast to a pointer to IFoo the pointer is adjusted as shown on the diagram. Instead of pointing to the start of the instance data it points to the IFoo part of the instance data.

The neat thing is that a caller using an IFoo pointer doesn't have any knowledge about the data surrounding the IFoo part of the class. The same can be said of for a caller using an IPlugin pointer. This pointer happens to point to the start of the instance data also pointed to by a Tester pointer but only a caller using a Tester pointer knows the entire layout of the instance data.

Using dynamic_cast requires RTTI (Run-Time Type Information) which is not on the diagram. The vtbl will contain additional type information that given a say IFoo pointer to an instance of Tester allows the code at run-time to discover the actual type of object pointed by the pointer and use that to downcast the pointer.

like image 86
Martin Liversage Avatar answered Sep 28 '22 09:09

Martin Liversage


What structure vtab actually has for instance of type Tester?

The mechanism of virtual dispatching is implementation-defined. vtable and vptr are not required by the C++ Standard and that knowledge isn't even necessary for programmers to program in C++, because you cannot access the virtual table (even if your compiler implements this); its generated by the compiler and added to your code, like it does lots of things to your code before it converts it into machine code.


Tester* t = new Tester();
IPlugin* plg = dynamic_cast<IPlugin*>(t);
IFoo* f = dynamic_cast<IFoo*>(plg);  

Here dynamic_cast is not needed in the second line. The following is enough:

Tester* t = new Tester();
IPlugin* plg = t;                 //upcast          - dynamic_cast not needed
IFoo* f=dynamic_cast<IFoo*>(plg); //horizontal-cast - dynamic_cast needed

dynamic_cast is not needed in upcast; its needed in downcast and horizontal-cast only.

Tester* tester1 = dynamic_cast<Tester*>(plg); //downcast - dynamic_cast needed
Tester* tester2 = dynamic_cast<Tester*>(f);   //downcast - dynamic_cast needed
like image 34
Nawaz Avatar answered Sep 28 '22 10:09

Nawaz


In ISO/IEC 14882 Second edition 2003-10-15 there is not exist such terms like vptr, virtual table, so it is completely up to compiler implementators.

Info about impl. in microsoft's visual C++: http://www.openrce.org/articles/files/jangrayhood.pdf

Article about impl. virtual tables in g++: http://phpcompiler.org/articles/virtualinheritance.html

like image 20
Konstantin Burlachenko Avatar answered Sep 28 '22 08:09

Konstantin Burlachenko


Virtual Mechanism(Virtual Pointer & Virtual Table) is not defined by the C++ standard. It is left out for the compiler to implement the mechanism in its own choosen way. It is an implementation detail of the compiler. Given that, the details of how the compiler will implement the virtual mechanism is abstracted from the user. What should matter is only the beahviors that are expected out of the virtual mechanism.

In your case:

Tester* t = new Tester(); 
IPlugin* plg = dynamic_cast<IPlugin*>(t); 
IFoo* f = dynamic_cast<IFoo*>(plg);   

plg & f both will point to a valid object of their respective types because t is derives from both of them.

Ofcourse this does not answer the specific question you asked but just wanted to clear the detail on virtual mechanism being a implementation detail of the compilers.

like image 38
Alok Save Avatar answered Sep 28 '22 08:09

Alok Save