home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!munnari.oz.au!metro!extro.ucc.su.OZ.AU!maxtal
- From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
- Subject: Re: Virtual base classes
- Message-ID: <1992Dec15.154004.8984@ucc.su.OZ.AU>
- Keywords: virtual, class
- Sender: news@ucc.su.OZ.AU
- Nntp-Posting-Host: extro.ucc.su.oz.au
- Organization: MAXTAL P/L C/- University Computing Centre, Sydney
- References: <1992Dec2.163139.8326@camax.com> <1992Dec3.202705.16646@ucc.su.OZ.AU> <rmartin.723768537@thor>
- Date: Tue, 15 Dec 1992 15:40:04 GMT
- Lines: 123
-
- 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 ------------------
-