Tools.h++ Manual

19-8 104011 Tandem Computers Incorporated
19
There are two approaches to disambiguating the call to
fun()
. Either change
it to:
fun((B)d); // We mean B's occurrence of A
or make
A
a virtual base class.
The first approach is error prone — the user must know the details of the
inheritance tree in order to make the proper cast.
The second approach, making
A
a virtual base class, solves this problem, but
introduces another: it becomes nearly impossible to make a cast back to the
derived class! This is because there are now two or more paths back through
the inheritance hierarchy or, if you prefer a more physical reason, the compiler
implements virtual base classes as pointers to the base class and you can't
follow a pointer backwards. The only solution is to exhaustively search all
possible paths in the object's inheritance hierarchy, looking for a match. (This
is the approach of the NIH Classes.) Such a solution is slow (it must be done for
every cast, although the search can be speeded up by "memoizing" the
resulting addresses), bulky and always complicated. We decided that this was
unacceptable.
Hence, we chose the first route. This can be made acceptable by keeping the
inheritance trees simple by not making everything derive from the same base
class. Hence, rather than using a large secular base class (sometimes dubbed
the "cosmic object"; an example is Smalltalk's "
Object
") with lots of
functionality, we have chosen to tease out the separate bits of functionality into
separate, smaller base classes.
The idea is to first build your object, then tack on the base class that will supply
the functionality that you need (such as collectability), thus avoiding multiple
base classes of the same type and the resulting ambiguous calls.
main () {
D d;
fun(d); // Which A ?
}
class A { };