简体   繁体   中英

where is the overridden virtual method saved in the vtable c++ in multiple inheritance

In C++, there is no class representation at run-time but I can always call an overridden virtual method in the derived class. where is that overridden method saved in the vtable? here's a piece of code to demonstrate:

struct B1 {
 virtual void f() { ... }
};
struct B2 {
 virtual void f() { ... }
 virtual void g() { ... }
};
struct D : B1, B2 {
 void f() { ... }
 virtual void h() { ... }
};

What's the memory layout for an object of class D ? Where are B1::f and B2::f saved in that memory layout (if they're saved at all) ?

An object d of Class D will have only a pointer to the VMT of class D , which will contain a pointer to D::f. Since B1:f and B2::f can be called only statically from the scope of D class, there is no need for object d to keep a dynamic pointer to those overridden methods.

This of cause is not defined in the standard, this is just the usual/logical implementation of the compiler.

In fact the picture is more complicated, since the VMT of class D incorporates the VMTs of classes B1 and B2. But anyway, there is no need to dynamically call B1::f until an object of class B1 is created.

When compiler uses vtable method of virtual dispatch * , the address of the overriden member function is stored in the vtable of the base class in which the function is defined.

Each class has access to vtables of all of its base classes. These vtables are stored outside of the memory layout for the class itself. Each class with virtual member functions, declared or inherited, has a single pointer to its own vtable. When you call an overriden member function, you supply the name of the base class whose member function you wish to call. The compiler knows about vtables of all classes, to it knows how to locate the vtable of your base class, does the lookup at compile time, and calls the member function directly.

Here is a short example:

struct A {
    virtual void foo()   { cout << "A"; }
};
struct B : public A { }; // No overrides
struct C : public B {
    virtual void foo()   { cout << "C"; }
    void bar()           { B::foo(); }
};

Demo.

In the example above the compiler needs to look up B::foo , which is not defined in class B . The compiler consults its symbol table to find out that B::foo is implemented in A , and generates the call to A::foo inside C::bar .

* vtables is not the only method of implementing virtual dispatch. C++ standard does not require vtables to be used.

Although nothing is mandated in the C++ standard, every known C++ implementation uses the same approach: every class with at least a virtual function has a vptr (pointer to vtable).

You didn't mention virtual inheritance which is a different, more subtle inheritance relation; non-virtual inheritance is a simple exclusive relation between a base class subobject and a derived class. I will assume all inheritance relations are not virtual in this answer.

Here I assume we derive from classes with at least a virtual function.

In case of single inheritance, the vptr from the base class is reused . (Not reusing it just wastes space and run time.) The base class is called " primary base class ".

In case of multiple inheritance, the layout of the derived class contains the layout of every base class, just like the layout of a struct in C contains the layout of every member. The layout of D is B1 then B2 (in any order actually, but the source code order is usually kept).

The first class is the primary base class: in D the vptr from B1 points to a complete vtable for D , the vtable with all the virtual functions of D . Each vptr from a non-primary base class points to a secondary vtable of D : a vtable with only the virtual functions from this secondary base class.

The constructor of D must initialize every vptr of the class instance to point to the appropriate vtable of D .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM