Click here to Skip to main content
15,886,362 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello Friends,

can you please help me in understanding vtable and vptr.

<a href="http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/">http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/</a>[<a href="http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/" target="_blank" title="New Window">^</a>]

I found above link pretty useful but few doubts

1)if i have code as follwos how many vtable will be created

C++
class base
{
public:
    virtual void display()
    {
        cout<<"i am in base";
    }
};
class derieved :public base
{
public:
    void display()
    {
        cout<<"i am in derieved";
    }
}
2)How vptr will be placed with class object(memory layout)

3)if there are 5 object created then how they will be linked with vtable and vpointer

Best Regards,
Vikas Mishra
Posted
Updated 20-Aug-12 5:33am
v2

Objects of both classes, base and derived, will in most implementation have a vtable pointer at the very start of the object's memory. (Although that is implementation dependent and not guaranteed by the C++ standard).

The vtable pointer of a base object points to base's vtable. This vtable will contain a pointer to base::display.

The vtable pointer of a derived object points to derived's vtable. This vtable will contain a pointer to derived::display in the slot, in which bases's vtable contains a pointer to base::display.

You can create any amount of objects of a class and they all contain a pointer to the same vtable, as there is only one vtable per class.

Thinks get considerably more complicated when using multiple inheritance, but at least in this example things are still relatively simple.

Hope that helps.
 
Share this answer
 
Comments
pasztorpisti 20-Aug-12 13:24pm    
5ed, and adding some more for the OP: when you inherit from multiple classes you object can have multiple vtable pointers, don't wanna know how because it isn't useful and can be compiler specific. With single line inheritance the vtable pointer is always at the beginning of your object - windows COM builds upon this heavily. Some more about how the vtable pointer gets to the beginning of your object: I will use your code as an example with your "base" and "derived" classes. When you create an instance of your derived class, the order of constructor calls is done starting from the base classes to the most derived classes. when the constructor of your base class is called, the beginning of the constructor contains a piece of automatically generated code that fills out the vtable pointer of your object to point to the vtable of the base class, then your code in the base constructor is executed. After this the constructor of derived is executed. The very beginning of the dervied constructor also contains automatically generated code that changes the vtable pointer from the base vtable pointer to the derived vtable pointer, after this your code in the derived constructor is executed. Warning!!! When the base constructor is executed the vtable pointer points to the base vtable and not to the derived vtable. why??? Because it makes no sense to call a virtual function in your derived class before the derived constructor is executed, a derived virtual method might want to use derived calss members that will be initialized only later in the derived constructor!!! For this simple reason if you call a virtual method form the base constructor it will execute the implementation that you have written in your base class even if you have overridden it in your derived class!!! calling a pure virtual method from the base class will cause compile error, but: if you pass the this pointer from your base constructor for example to a static global function somewhere in your code, that other function can call the pure virtual methods of the base class and at this time that causes a "pure virtual function call" runtime error!!! because you called the pure virtual method of a half-constructed object. My advice: never call virtual functions from construcotors!!! The same is true for destrucotrs for the very same reason!!!

EDIT: As you might noticed, using the vtable in the base class is dangerous and you might not want to use it at all. If you don't want to use it, then it has no point to fill it out because the derived constructor will do the job later. For this reason there is a __declspec(novtable) in VC++ that can be used to turn off vtable pointer initialization in abstract base classes when you are serious about optimization.
Sergey Alexandrovich Kryukov 20-Aug-12 13:38pm    
I 5ed it, too, but, if I'm not much mistaken, such layout is only possible when there is no multiple inheritance...
Good notes, by the way.
--SA
pasztorpisti 20-Aug-12 14:10pm    
A single inheritance is the building block of multiple inheritance, the sub objects of a complex class are built up similarly. The only exception is virtual inheritance where its not clear which derived class should initialize the virtual part of the object. In that case each owner has a pointer to the virtual part and there is a flag that indicates whether the virtual part has already been initialized or not coz every sub objects tries to initialize it at some point. What happens when multiple subobjects with a common virtual base override different (or maybe the same) virtual methods of a virtual base... Good question! Maybe a compile time error or compiler crash... :-) But in general I'm against virtual inheritance, in my opinion its avoidable and I recommend avoiding it!

I didnt remember how virtual base classes are initialized: http://msdn.microsoft.com/en-us/library/38tx22fy.aspx
But still dont know what happens when we mix in virtual function overrides in the derived subclasses.
Sergey Alexandrovich Kryukov 20-Aug-12 15:45pm    
Here is the thing: I remember that when we discovered C++ vtable in order to better implement weak form of multiple inheritance (to implement interface implementations in a smart way), we found that in multiple inheritance, the pointers to the same object as the pointers of different base types, physically point to different point withing the same vtable. After discussion, we came to the conclusion that such situation is unavoidable with multiple inheritance, and not the case with single inheritance. By the way, it means that proper type cast in multiple inheritance actually shifts the pointer accordingly. Come to think about, it looks pretty logical. Interesting, isn't it.

To make it more interesting, one my friend, experimental physicist, never worked as a professional developer (I think because he programs my better then they :-), analyzed that multiple inheritance mechanism and found it very inflexible (nothing new so far). He invented an alternative method based on one extra level of indirection (in general case, two tables instead of one vtable) and argued that the performance toll is insignificant next to the benefit. One of the benefits looks like that: in multiple inheritance, the inheritance can be virtual or not, but this is defined in some base class and cannot be changed later, by subclassing. In hist approach, declaring of the inheritance as virtual or not is itself a subject of late binding; that is, it is decided at the point where a derived class is created and can be changed back and forth in further inheritance. Who can bit that? In my view, this is certainly one way of going out of one of multiple-inheritance dead ends...

--SA
Sergey Alexandrovich Kryukov 20-Aug-12 15:45pm    
Here is the thing: I remember that when we discovered C++ vtable in order to better implement weak form of multiple inheritance (to implement interface implementations in a smart way), we found that in multiple inheritance, the pointers to the same object as the pointers of different base types, physically point to different point withing the same vtable. After discussion, we came to the conclusion that such situation is unavoidable with multiple inheritance, and not the case with single inheritance. By the way, it means that proper type cast in multiple inheritance actually shifts the pointer accordingly. Come to think about, it looks pretty logical. Interesting, isn't it?

To make it more interesting, one my friend, experimental physicist, never worked as a professional developer (I think because he programs my better then they :-), analyzed that multiple inheritance mechanism and found it very inflexible (nothing new so far). He invented an alternative method based on one extra level of indirection (in general case, two tables instead of one vtable) and argued that the performance toll is insignificant next to the benefit. One of the benefits looks like that: in multiple inheritance, the inheritance can be virtual or not, but this is defined in some base class and cannot be changed later, by subclassing. In hist approach, declaring of the inheritance as virtual or not is itself a subject of late binding; that is, it is decided at the point where a derived class is created and can be changed back and forth in further inheritance. Who can bit that? In my view, this is certainly one way of going out of one of multiple-inheritance dead ends...

--SA
Just to add one more interesting thing. Visual studio debugger can show the virtual functions associated with objects. when you add object in to watch you can see an item with name __vfptr it will contains the address of table (also with a name like class::vftable something like that)

jkchan
http://cgmath.blogspot.com[^]
 
Share this answer
 
Thank you so much Guys for this great explanation...I will initiate one more topic with object slicing with Virtual function.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900