From: eb@ascent.com (Ed Barton)
Subject: Re: member test?
In-reply-to: sakkinen@jyu.fi's message of Tue, 10 Nov 1992 07:01:24 GMT
Date: 11 Nov 92 12:30:53
	<1992Nov10.070124.5763@jyu.fi>
Organization: Ascent Technology, Inc., Cambridge Massachusetts


In article <1992Nov10.070124.5763@jyu.fi> sakkinen@jyu.fi (Markku Sakkinen) writes:
   In article <EB.92Nov9085335@ascent.ascent.com> eb@ascent.com (Ed Barton) writes:
   >In article <1992Nov6.081658.29693@bernina.ethz.ch> haechler@bernina.ethz.ch (Stefan Haechler) writes:
   >   How can I know which dynamic type has a variable ?
   > ...
   >The software-design answer is that you shouldn't have to know the
   >answer to this question, and that there may be something wrong with
   >the design if you need to ask it.  If you know only that something is
   >a pointer-to-A, you should be using only the methods and virtual
   >functions that are part of the interface defined by class A.
   > ...
   Come on, there are many fully reasonable and legitimate situations
   in which one needs to know this.  And C++ is almost the only OOPL
   I know of in which you cannot ask the dynamic type of an object.

At the risk of starting up a whole RTTI discussion again, let me try
to clarify what I mean.  I said there _may_ be something wrong with
the design if you are trying to ask the dynamic type of an object.  I
still believe that the design is _likely_ to be flawed, especially if
it being constructed by a beginning C++ programmer.

If your design requires a downcast that might be unsafe, you need a
way to check whether the downcast is OK.  However, in the LISP world I
have seen many programs which used dynamic type-checks where they were
not really appropriate.  When a programmer with experience in some
other object-oriented language has the impulse to ask the dynamic type
of an object, the programmer should stop and consider whether that is
really what is needed.  It is easy to have the impulse if that's the
way you have been coding, even if a bit of reflection would show that
a virtual function identifying a well-defined redefinable operation
would be better than a hard-wired and non-extensible conditional.  In
other situations, the impulse might occur because the type information
has been lost by casting to Object* for storage into a container, when
actually the use of a type-safe template class would be better.

C++ is more serious than most object-oriented languages about making
the programmer specify the interface through which an object is to be
accessed, and attempting to enforce that interface through the type
system.  It provides mechanisms such as virtual functions and
templates that go some distance toward keeping type-safe programs
flexible enough to be useful.  It does not currently provide the type
of dynamic type query that was requested.  Out of all the situations
where one is tempted to query the dynamic type of an object, many of
them can be better handled with the existing mechanisms, and some
residue will be left over.  I don't claim that this residual set is
nonempty, and I would be happy to see a limited form of RTTI for that
set.  (Others might disagree, and say that dynamic type-querying is
always a poor design outside of debuggers and such.)

However, I don't think programmers should fall back on RTTI until they
have thought about other solutions that are more explicit and more
type-safe.  Is the conditionalized code really implementing an
operation that should be part of the interface of the base type, i.e.,
a virtual function?  Is the type information being thrown away earlier
through inappropriate casting?  Is it really the type that ought to be
queried, or is the code really looking for some behavioral property of
the object that might be implemented by many different subclasses, and
again should be queried through a virtual function?  I have seen a lot
of LISP code that did something or other if (eq (type-of object)
'frobozz), and hence wouldn't work for subclasses of frobozz.  And so
forth.


Xref: sparky comp.lang.c++:15996 comp.std.c++:1523