Inheritance is one of those object-oriented features whose importance is perhaps overstated. When I was first being introduced to OO, it was a lot of “code reuse!” and “polymorphism!” and “code reuse!” In practice, inheritance is usually a way to tightly couple two different classes and create more headaches and rework in the future.

That’s why many OO languages favor interfaces, and why the classic Gang-of-Four patterns emphasize the importance of composition in many situations. And, because inheritance can make things complicated, most languages also require single parent inheritance.

Most languages. C++, on the other hand, doesn’t. In C++, I could define a class Car, a class Truck, and then do this:

class ElCamino : Car, Truck {}

As you can imagine, this introduces all sorts of problems. What if both Car and Truck have a method with the same signature? Or worse, what happens if they have the same ancestor class, MotorVehicle? If MotorVehicle defines drive(), and Car and Truck both inherit drive(), where does ElCamino get its drive() function from?

This scenario is known as the Diamond Problem. And C++ offers a simple solution to the Diamond Problem: virtual inheritance.

If, for example, our classes are defined thus:

class Car : virtual MotorVehicle {};
class Truck : virtual MotorVehicle {};
class ElCamino : Car, Truck {};

ElCamino will inherit drive() directly from MotorVehicle, even though both its ancestors also inherited from MotorVehicle. An ElCamino is both a Car and a Truck, but is only a MotorVehicle once, not twice, so anything it inherits from MotorVehicle should only be in the class once.

Now, in practice, multiple-inheritance is one of those luxury foot-guns which allows you to blow off your own foot using anything that implements the shoot() method at the same time. It does have uses, but seeing it used is a bit of a code smell.

Mindy found some code which doesn’t use multiple inheritance. Nowhere in their codebase is there a single instance of multiple inheritance. But her co-worker wants to future-proof against it, or maybe just doesn’t understand what virtual inheritance is, so they’ve manually gone through the codebase and made every child class inherit virtually.

This hasn’t broken anything, but it’s lead to some dumb results, like this:

class SomeSpecificDerivedClass final : public virtual SomeBaseClass
{
   /* ... code ... */ 
};

The key note here is that our derived class is marked as final, so no one is ever going to inherit from it. Ever. It’s sort of a belts and braces approach, except you’re wearing a dress.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!