There's an overhead, try it:
#include <iostream>
struct Foo {
int a;
};
struct Bar : Foo {
int b;
};
struct Baz : virtual Foo {
int b;
};
int main() {
std::cout << sizeof(Foo) << " ";
std::cout << sizeof(Bar) << " ";
std::cout << sizeof(Baz) << "\n";
}
On my implementation I get 4 8 16
. Virtual inheritance requires a vptr or equivalent mechanism, because the class Baz
does not know at what offset the Foo
base class sub-object will appear relative to the Baz
base class sub-object. It depends whether the most-derived type also inherits Foo
by another route.
Since the vptr is there, one also expects that in certain circumstances it will be used, which is more overhead :-) That is, one or more additional indirections are required in order to access Foo::a
via a Baz*
or Baz&
. The compiler might choose to avoid that if it somehow knows the most-derived type of the referand.