Besides textbook examples -- in the real world -- does it ever make sense to use multiple inheritance (where more than one of the base classes are not pure interfaces) in C++?
Easiest to point at iostream
, which inherits from istream
and ostream
. cin
and cout
are istream
and ostream
respectively but fstream
derives from iostream
.
Microsoft's ATL (Active Template Library) uses multiple inheritance as mixin classes:
I have used multiple inheritance in the 'real world' - in a job where I was involved in coding a mapping application.
Unfortunately, I cannot remember the exact example which I find incredibly frustrating.
However, here is an interesting article about points to consider and alternative patterns or solutions to consider using:
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.2
I like the use of vehicles for the examples - particularly adding in the amphibious vehicle.
Multiple inheritance definitely has its place and it can be very useful. As a general guideline a base class should be abstract whenever possible, which means you shouldnt be able to create an object out of it, but nothing stop you from inheriting from concrete class. It is definitely a merit too t hat you can take advantage of the inherited implementation from base class. Example on one of the answer on iostream is a good one. Another example is perhaps to say modelling a employee who is also an owner/director of a business and you will model it as
public class Director
{
................
double CalculateDividend();
bool ApproveBudget();
};
public class Employee
{
................
double CalculateSalary();
};
public class WorkingDirector: Employee, Director
{
..............
};
Now a WorkingDirector object can do what an Employee and a Director can do, which is a perfect in realworld. We wouldnt even need to overwrite any method implementation.
In many cases implementing design patterns are also made easier with multiple inheritance support.
IMO, it's open to argument. Prior to templates, there were a fair number of cases that justified it. Basically, you could use base classes about like you can use policy classes with templates. For example, consider a template like:
template <typename policy1, typename policy2>
class whatever {
policy1 p1;
policy2 p2;
public:
void dosomething() { if (p1.enquire()) p2.dosomething(); }
};
If you'd rather not use templates for some reason, you can get (some) fairly similar capabilities with multiple inheritance:
class whatever : policy1, policy2 {
void dosomething() { if (enquire()) dosomething(); }
};
In both cases, you're basically embedding an instance of the "policy" into your new object. Since we're using private inheritance, there's no concern with the LSP -- much like with policy-based templates, the intent isn't to create a large hierarchy that asserts anything about relationships between the members of the hierarchy -- rather, it's simply about creating the ability to create a large variety of unrelated classes on demand.