Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many vptr will a object of class(uses single/multiple inheritance) have?

How many vptrs are usually needed for a object whose clas( child ) has single inheritance with a base class which multiple inherits base1 and base2. What is the strategy for identifying how many vptrs a object has provided it has couple of single inheritance and multiple inheritance. Though standard doesn't specify about vptrs but I just want to know how an implementation does virtual function implementation.

like image 979
Passionate programmer Avatar asked Jul 27 '10 08:07

Passionate programmer


People also ask

How many VPTR does a class have?

In a typical vtable-based implementation of virtual polymorphism, there will be: one vtable per class, containing the virtual function pointers and other metadata for that class; one vptr per object, pointing to the vtable for that object's dynamic class type.

Is VPTR inherited?

The Virtual Pointer (vptr) is inherited by all subclasses, so the vptr of the Shape class will be automatically available in all its subclasses, such as Rectangle, Circle, etc. The Virtual Pointer (vptr) must be initialized to point to the corresponding Virtual Table (vtbl) in every instance (object) of a class.

How many Vptrs are there in C++?

There is only one VPTR for each object when using simple inheritance like this. The VPTR must be initialized to point to the starting address of the appropriate VTABLE. (This happens in the constructor, which you'll see later in more detail.)

How many VPTR will be created internally for following program?

But, compiler set only one public VPTR in base class internally. If 2nd Vtable is required to be initialized then the same VPTR is inherited and used at run time. Note that Constructors initializes the VPTR. So, answer is 1 public VPTR in base class.

What is VPTR?

Explanation: vptr is abbreviated for a virtual pointer which is used to point virtual tables of a class.


1 Answers

Why do you care? The simple answer is enough, but I guess you want something more complete.

This is not part of the standard, so any implementation is free to do as they wish, but a general rule of thumb is that in an implementation that uses virtual table pointers, as a zeroth approximation, for the dynamic dispatch you need at most as many pointers to virtual tables as there are classes that add a new virtual method to the hierarchy. (In some cases the virtual table can be extended, and the base and derived types share a single vptr)

    // some examples:
    struct a { void foo(); };           // no need for virtual table
    struct b : a { virtual foo1(); };   // need vtable, and vptr
    struct c : b { void bar(); };       // no extra virtual table, 1 vptr (b) suffices
    struct d : b { virtual bar(); };    // 1 vtable, d extends b's vtable

    struct e : d, b {};                 // 2 vptr, 1 for the d and 1 for b                                      
    struct f : virtual b {};            // 1 vptr, f reuse b's vptr to locate subobject b
    struct g : virtual b {};            // 1 vptr, g reuse b's vptr to locate subobject b
    struct h : f, g {};                 // 2 vptr, 1 for f, 1 for g
                                        // h can locate subobject b using f's vptr

Basically each subobject of a type that requires its own dynamic dispatch (cannot directly reuse the parents) would need its own virtual table and vptr.

In reality compilers merge different vtables into a single vtable. When d adds a new virtual function over the set of functions in b, the compiler will merge the potential two tables into a single one by appending the new slots to the end of the vtable, so the vtable for d will be a extended version of the vtable for b with extra elements at the end maintaining binary compatibility (i.e. the d vtable can be interpreted as a b vtable to access the methods available in b), and the d object will have a single vptr.

In the case of multiple inheritance things become a bit more complicated as each base needs to have the same layout as a subobject of the complete object than if it was a separate object, so there will be extra vptrs pointing to different regions in the complete object's vtable.

Finally in the case of virtual inheritance things become even more complicated, and there might be multiple vtables for the same complete object with the vptr's being updated as construction/destruction evolves (vptr's are always updated as construction/destruction evolves, but without virtual inheritance the vptr will point to the base's vtables, while in the case of virtual inheritance there will be multiple vtables for the same type)

like image 70
David Rodríguez - dribeas Avatar answered Sep 22 '22 16:09

David Rodríguez - dribeas