2

I've read a lot of posts and everyone says, that virtual table is per class, not per object and object only has _vtpr pointer to shared vtable. But please consider this example:

class Base
{
public:
    virtual void func1(void) {}
    virtual void func2(void) {}
private:
    int dummy;
};

class Der1 : public Base
{
public:
    virtual void func1(void) {}
private:
    int dummy;
};

class Der2 : public Base
{
public:
    virtual void func2(void) {}
private:
    int dummy;
};

int main(void)
{
    Base * obj1 = new Der1;
    Base * obj2 = new Der2;
}

Does obj1 and obj2 relates to that one unique Base class vtable? I believe the answer is no, but can you please explain? And if both of these objects do relate to the same vtable, how it is determined which methods to be called? For example, obj1->func1 reference is different than obj2->func1.

UPDATE:
What operations are executed when doing Base * obj1 = new Der1;? Can someone write a pseudo code for these actions?

  • 2
    vtable is not defined in the C++ standard. It means that compiler implementers are free to do whatever they want. There is even no guarantee that there will be any vtable at all. This is the one of the major reasons of why we don't have a C++ ABI. Tell that to "everyone" who "says". – Ivan Aksamentov - Drop Apr 10 '16 at 20:03
  • Presumably `Der1` and `Der2` each have their own vtable, non? – Kerrek SB Apr 10 '16 at 20:07
  • 1
    Spefically check this [answer](http://stackoverflow.com/a/562240/2352671) by [Johannes Schaub - litb](http://stackoverflow.com/users/34509/johannes-schaub-litb) – 101010 Apr 10 '16 at 20:09
  • @Drop, yes, I know that. It was my mistake that I did not mentioned in which toolchain spec I am interested. And that is not surprising — GCC. – Karolis Milieška Apr 10 '16 at 20:30

1 Answers1

1

I hope the following illustration will help. Derived classes just copy the virtual table of base class, but they may modify the appropriate entry. The red part shows that given class has modified the entry in v-table. So, when instance of derived class is created, the modified table (specific to that class) is taken into consideration.

It is up to the compiler how duplicity of base class is handled (if base class has large number of functions - would derived have copy of entire virtual function table, and would modify the entries?). IMO, compiler will simply copy entire table for each derived class to keep things simple. Searching appropriate method to call then becomes simple. enter image description here

Ajay
  • 18,086
  • 12
  • 59
  • 105
  • Where and when new vtables will be located? Correct me if I am wrong: at the compile Der1 and Der2 vtables will be created into RW data section; When assigning Base * obj1 = new Der1; and calling by obj1->func1(), Der1 vtable will be dereferenced to find the entry of that particular method. And since Base * obj1 and obj2 are only pointers, they do not have and copied to vtable. – Karolis Milieška Apr 10 '16 at 20:22
  • So can you approve my understanding on this or I am wrong? – Karolis Milieška Apr 11 '16 at 04:57
  • I don't know about data-sections, and how compiler/linker exactly puts the v-tables. Conceptually, you can consider v-tables as global-linked lists. A given class holds one of the v-table's head (and hence the size of class is added by `sizeof(pointer)`). A derived class would create another v-table linked-list, and class (not instance) would point to that linked list. If derived class doesn't re-define a virtual function, it would point to existing v-table linked list. A virtual class hierarchy may point to multiple such linked list heads, and hence size gets increased. Please read book/onlin – Ajay Apr 11 '16 at 06:25