Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a virtual function from a derived pointer without paying the vtable price

Considering this simple example:

class Base {
    virtual void foo() {};  
};

class Derived: public Base {
    void foo() {}; 
}; 

Base    *b = new Derived;
Derived *d = new Derived;
b->foo();
d->foo();

My question is: does a call to a member function declared as virtual in a base class (but not in the derived class) through a derived class pointer uses (and pay the price for) the vtable mechanism ? In the example b->foo() uses the vtable mechanism to call the Derived::foo(), but d->foo()?

If yes, how circumvent this behavior: when using explicitly a Derived pointer, I would like to directly call the Derived::foo() method without paying the cost of the vtable, as if the base class does not exist?

like image 690
janou195 Avatar asked Nov 21 '25 09:11

janou195


2 Answers

The syntax

d->Derived::foo();

will suppress virtual dispatch and guarantee that the function Derived::foo is the one called, even in the presence of overriding functions.

This is rarely what you want, but I cannot suggest alternative solutions unless you explain why you're trying to do this. For example, in the code snippet given, there is no reason why the Derived should be dynamically allocated at all. You could just write this instead:

Derived d;
d.foo();

Here, the compiler knows for sure that the dynamic type is Derived, so no virtual dispatch is needed.

like image 124
Brian Bi Avatar answered Nov 22 '25 22:11

Brian Bi


does a call to a member function declared as virtual in a base class (but not in the deverived class)...

I've stopped to read here, because if Base declare foo as virtual, Derived can only override foo, Derived::foo (supposedly signature match) is implicitly virtual.

The following definitions of Derived::foo are identical:

class Derived: public Base {
  void foo() {}; 
};

class Derived: public Base {
  virtual void foo() {}; 
};

This mechanism is called implicit virtual propagation, and this SO answer tries and explain why id was conceived that way. Here is the rationale about it:

10.3 Virtual functions

2 If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

like image 42
YSC Avatar answered Nov 22 '25 23:11

YSC