Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When virtual inheritance IS a good design?

EDIT3: Please be sure to clearly understand what I am asking before answering (there are EDIT2 and lots of comments around). There are (or were) many answers which clearly show misunderstanding of the question (I know that's also my fault, sorry for that)

Hi, I've looked over the questions on virtual inheritance (class B: public virtual A {...}) in C++, but did not find an answer to my question.

I know that there are some issues with virtual inheritance, but what I'd like to know is in which cases virtual inheritance would be considered a good design.

I saw people mentioning interfaces like IUnknown or ISerializable, and also that iostream design is based on virtual inheritance. Would those be good examples of a good use of virtual inheritance, is that just because there is no better alternative, or because virtual inheritance is the proper design in this case? Thanks.

EDIT: To clarify, I'm asking about real-life examples, please don't give abstract ones. I know what virtual inheritance is and which inheritance pattern requires it, what I want to know is when it is the good way to do things and not just a consequence of complex inheritance.

EDIT2: In other words, I want to know when the diamond hierarchy (which is the reason for virtual inheritance) is a good design

like image 340
Roman L Avatar asked Jan 05 '11 15:01

Roman L


People also ask

When should you use virtual inheritance?

Virtual inheritance is used when we are dealing with multiple inheritance but want to prevent multiple instances of same class appearing in inheritance hierarchy. From above example we can see that “A” is inherited two times in D means an object of class “D” will contain two attributes of “a” (D::C::a and D::B::a).

Why do we use virtual in inheritance?

Virtual base classes are used in virtual inheritance in a way of preventing multiple “instances” of a given class appearing in an inheritance hierarchy when using multiple inheritances.

How does virtual inheritance solve the diamond problem?

Virtual inheritance solves the classic “Diamond Problem”. It ensures that the child class gets only a single instance of the common base class. In other words, the Snake class will have only one instance of the LivingThing class. The Animal and Reptile classes share this instance.

Why virtual classes are important in the case of multiple inheritance?

Instead, if classes B and C inherit virtually from class A, then objects of class D will contain only one set of the member variables from class A. As you probably guessed, this technique is useful when you have to deal with multiple inheritance and it's a way to solve the infamous diamond inheritance.


1 Answers

If you have an interface hierarchy and a corresponding implementation hierarchy, making the interface base classes virtual bases is necessary.

E.g.

struct IBasicInterface {     virtual ~IBasicInterface() {}     virtual void f() = 0; };  struct IExtendedInterface : virtual IBasicInterface {     virtual ~IExtendedInterface() {}     virtual void g() = 0; };  // One possible implementation strategy struct CBasicImpl : virtual IBasicInterface {     virtual ~CBasicImpl() {}     virtual void f(); };  struct CExtendedImpl : virtual IExtendedInterface, CBasicImpl {     virtual ~CExtendedImpl() {}     virtual void g(); }; 

Usually this only makes sense if you have a number of interfaces that extend the basic interface and more than one implementation strategy required in different situations. This way you have a clear interface hierarchy and your implementation hierarchies can use inheritance to avoid the duplication of common implementations. If you're using Visual Studio you get a lot of warning C4250, though.

To prevent accidental slicing it is usually best if the CBasicImpl and CExtendedImpl classes aren't instantiable but instead have a further level of inheritance providing no extra functionality save a constructor.

like image 147
CB Bailey Avatar answered Oct 15 '22 16:10

CB Bailey