Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any penalty/cost of virtual inheritance in C++, when calling non-virtual base method?

Tags:

Does using virtual inheritance in C++ have a runtime penalty in compiled code, when we call a regular function member from its base class? Sample code:

class A {     public:         void foo(void) {} }; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {};  // ...  D bar; bar.foo (); 
like image 410
Goofy Avatar asked Apr 05 '11 14:04

Goofy


People also ask

What happens if we don't use a virtual function in the inheritance?

If you don't use virtual functions, you don't understand OOP yet. Because the virtual function is intimately bound with the concept of type, and type is at the core of object-oriented programming, there is no analog to the virtual function in a traditional procedural language.

Should we always use virtual inheritance if yes why if not why not?

The answer is definitely no. The base of an idiomatic answer can be the most fundamental idea of C++: you only pay for what you use. And if you don't need virtual inheritance, you should rather not pay for it. Virtual inheritance is almost never needed.

Why we need to define virtual base class in hybrid inheritance explain with example?

Virtual base classes offer a way to save space and avoid ambiguities in class hierarchies that use multiple inheritances. When a base class is specified as a virtual base, it can act as an indirect base more than once without duplication of its data members.

How many copies of base class are created for virtual inheritance?

Virtual inheritance is a C++ technique that ensures only one copy of a base class's member variables are inherited by grandchild derived classes.


2 Answers

There may be, yes, if you call the member function via a pointer or reference and the compiler can't determine with absolute certainty what type of object that pointer or reference points or refers to. For example, consider:

void f(B* p) { p->foo(); }  void g() {     D bar;     f(&bar); } 

Assuming the call to f is not inlined, the compiler needs to generate code to find the location of the A virtual base class subobject in order to call foo. Usually this lookup involves checking the vptr/vtable.

If the compiler knows the type of the object on which you are calling the function, though (as is the case in your example), there should be no overhead because the function call can be dispatched statically (at compile time). In your example, the dynamic type of bar is known to be D (it can't be anything else), so the offset of the virtual base class subobject A can be computed at compile time.

like image 128
James McNellis Avatar answered Oct 18 '22 22:10

James McNellis


Yes, virtual inheritance has a run-time performance overhead. This is because the compiler, for any pointer/reference to object, cannot find it's sub-objects at compile-time. In constrast, for single inheritance, each sub-object is located at a static offset of the original object. Consider:

class A { ... }; class B : public A { ... } 

The memory layout of B looks a little like this:

| B's stuff | A's stuff | 

In this case, the compiler knows where A is. However, now consider the case of MVI.

class A { ... }; class B : public virtual A { ... }; class C : public virtual A { ... }; class D : public C, public B { ... }; 

B's memory layout:

| B's stuff | A's stuff | 

C's memory layout:

| C's stuff | A's stuff | 

But wait! When D is instantiated, it doesn't look like that.

| D's stuff | B's stuff | C's stuff | A's stuff | 

Now, if you have a B*, if it really points to a B, then A is right next to the B- but if it points to a D, then in order to obtain A* you really need to skip over the C sub-object, and since any given B* could point to a B or a D dynamically at run-time, then you will need to alter the pointer dynamically. This, at the minimum, means that you will have to produce code to find that value by some means, as opposed to having the value baked-in at compile-time, which is what occurs for single inheritance.

like image 24
Puppy Avatar answered Oct 18 '22 23:10

Puppy