From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Re: Virtual base classes
Keywords: virtual, class
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Tue, 15 Dec 1992 15:40:04 GMT

rmartin@thor.Rational.COM (Bob Martin) writes:
>maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
>|kotula@camax.com (Jeff Kotula) writes:
>|>
>|>  	  A
>|>       / \
>|>       B C
>|>       | |
>|>       D E
>|>       \ /
>|>	  F
>|>
>|>where we only want one copy of A, which set of inheritances should be
>|>virtual?
>|>
>
>|	All of them.
>
>|	As a rule of thumb, all public inheritance should be made virtual,
>|	private inheritance non-virtual. (See papers by Markku Sakkinen
>|	for a full explanation of why)
>
>
>(I'd like to see these papers.  Can you post a reference?)

	The author is sakkinen@jytko.jyu.fi, and regularly
contibutes to comp.std.c++.

>
>I am in some disagreement with the above statement.  Virtual
>inheritance is a necessary evil IMHO.  It hobbles the language in
>several important ways.  It prevents valid downcasting.  (No flames
>please.  I know downcasting is suboptimal, but prior to covariant return
>types it is sometimes necessary).  

	OK, I wont argue :-)

>Also, VI adds some minor
>inefficiencies to virtual dispatch.  The worst aspect of VI, and the
>one which I suspect makes you want to declare all public inheritance
>as virtual, is that it must be used long before you know you need it.
>i.e. In the diagram above, it is B and C which must virtually inherit
>from A, but it is not until you have recognized the need for F that
>you know that virtual inheritance is needed.  

	Apart from problems with efficiency and downcasting,
the rationale is that ALL 'isA' relations, and especially
abstractions, *must* be declared virtual anyhow. The reason
is that such base classes should not ever be replicated,
they must always be shared, and virtual inheritance is the
only way to ensure this.

	If you do not do this, you break an important
reusability principle, namely that the bases remain open.

>
>This is really quite sick.  Proper design of a project can alleviate
>this a bit since the design will alert you to the need before you have
>written any of the classes.  But the problem can still occur later if
>you extend the project by creating new classes.

	Therefore, always use virtual with public. Then,
after the project is running but a bit slow and big, you can
remove some of the unneccesary virtuals if you really have to.
But you can only do this at the point of *closing*, when you
will never extend or reuse the classes.
>
>I wish there were a way to declare F in such a way that you could say
>that A should be a virtual base.  

	The only time you need non-virtual is when you require
replicated inheritance. Most of them are cases where the derivation
should also be private, because you are not implementing an 'isA'
relation but just doing an implementation.

	But there are cases where you DO want
to allow:

	A		A
	/\		/\
	B C		D E
	\/		\/
	F		G
	\		/
	      H

and you cant do this at all.

>
>Despite this, I don't think it is acceptable to proliferate the
>disadvantages of virtual inheritance by making all public inheritance
>virtual.
>
>BTW.  I think private inheritance is a very weak construct that should
>be avoided altogether.  There is nothing that can be done with private
>inheritance, that cannot be done, just as simply, with containment.
>
	Yes there is: you cant override virtuals with
containment.

	Your view tends to indicate inheritance should principally
be used for subclassing (isA). In that case it is correct
to make all inheritance virtual. The corresponding inefficiency
is then a consequence of the open/closed principle: the
virtual pointers are required if the classes are to be genuinely
open for arbitrary extension.

	They can be removed only be closing off a class and preventing
its use as a base. This might be done with a private nested class,
in which case you could sensibly omit 'virtual' to gain
efficiency.

	In practice, I omit virtual most of the time,
but then, I control all my classes, and can modify the lot
and recompile all my programs if I need to: they dont need to
be open and closed in the same sense as library classes
published for all to use.

-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Newsgroups: comp.lang.c++