I often use pure virtual classes (interfaces) to reduce dependencies between implementations of different classes in my current project. It is not unusual for me to even have hierarchies in which I have pure virtual and non-pure virtual classes that extend other pure virtual classes. Here is an example of such a situation:
class Engine
{ /* Declares pure virtual methods only */ }
class RunnableEngine : public virtual Engine
{ /* Defines some of the methods declared in Engine */ }
class RenderingEngine : public virtual Engine
{ /* Declares additional pure virtual methods only */ }
class SimpleOpenGLRenderingEngine : public RunnableEngine,
public virtual RenderingEngine
{ /* Defines the methods declared in Engine and RenderingEngine (that are not
already taken care of by RunnableEngine) */ }
Both RunnableEngine
and RenderingEngine
extend Engine
virtually so that the diamond problem does not affect SimpleOpenGLRenderingEngine
.
I want to take a preventative stance against the diamond problem instead of dealing with it when it becomes a problem, especially since I like to write code that is as easy for someone else to use as possible and I don't want them to have to modify my classes so that they can create particular class heirarchies e.g. if Bob wanted to do this:
class BobsRenderingEngine : public virtual RenderingEngine
{ /* Declares additional pure virtual methods only */ }
class BobsOpenGLRenderingEngine : public SimpleOpenGLRenderingEngine,
public BobsRenderingEngine
{ /* Defines the methods declared in BobsRenderingEngine */ }
This would not be possible if I had not made SimpleOpenGLRenderingEngine
extend RenderingEngine
virtually. I am aware that the probability of Bob wanting to do this may be very low.
So, I have begun using the convention of always extending pure virtual classes virtually so that multiple inheritance from them does not cause the diamond problem. Maybe this is due to me coming from Java and tending to only use single inheritance with non-pure virtual classes. I'm sure it is probably overkill in some situations but are there any downsides to using this convention? Could this cause any problems with performance/functionality etc.? If not I don't see a reason not to use the convention, even if it may often not be needed in the end.
AImpl : public virtual IA
, then using virtual inheritance you may define aclass B : public virtual IA, public AImpl
. Thus B will use AImpl's implementation of IA. – ShandyB
to extendIA
explicitly in your example by the example in my question is similar. – Inarch