home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.c++:11509 comp.std.c++:950
- Newsgroups: comp.lang.c++,comp.std.c++
- Path: sparky!uunet!stanford.edu!lucid.com!lucid.com!jss
- From: jss@lucid.com (Jerry Schwarz)
- Subject: Re: run-time type checking (was: Re: Covariant Types in Derived Classes)
- Message-ID: <1992Jul25.022147.24152@lucid.com>
- Sender: usenet@lucid.com
- Reply-To: jss@lucid.com (Jerry Schwarz)
- Organization: Lucid, Inc.
- References: <1992Jul22.022218.1115@cadsun.corp.mot.com> <1992Jul23.154254.5306@ucc.su.OZ.AU> <1992Jul24.143359.3602@advtech.uswest.com> <1992Jul24.192207.15267@ucc.su.OZ.AU>
- Date: Sat, 25 Jul 92 02:21:47 GMT
- Lines: 74
-
- In article <1992Jul24.192207.15267@ucc.su.OZ.AU>, maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
- |>
- |> But that wont PROVE anything. You have to give me
- |> an example of a system that uses downcasting and then I'll
- |> show how to write it without downcasting.
- |>
- |> Please restrict examples to domestic systems, since
- |> I already agree all bets are off for foreign systems and
- |> also for introspective ones like, say, debuggers, OODBMS,
- |> etc.
- |>
- |> Lets agree for example to restrict ourselves to
- |> text input and output and no disk storage. Lets agree
- |> that the program must handle a fixed number of types.
- |> And that it reads text in, does some calculations,
- |> and then prints the answers.
- |>
- |> Such a program creates ALL the objects, manipulates
- |> them, and then it terminates.
- |>
-
- Here is a typical example of my use of downcasting. Downcasting
- is not essential in this example, but I think it makes the design
- cleaner.
-
- I want to define an "indent stream" derived from ostream.
- An indent stream contains an indentation level.
-
- class indentstream : public ostream {
- public:
- int level ; // Public only to keep example short.
- indentstream(streambuf* sb) : ostream(sb), level(0) { }
- } ;
-
- The level is used by a manipulator.
-
- ostream& newline(ostream& os) {
- indentstream* is = CAST<indentstream*>os ; // notation suggestive
- os.put(\n) ;
- if ( is ) {
- for ( int n = 0 ; n < is->level ; ++n ) is.put('\t') ;
- }
- os.flush() ;
- }
-
- Typical uses look like
-
- indentstream myout(...) ;
- ...
- myout.level++ ;
- // x and y inserters do not have to understand indentation as long
- // as they put everything on a single line.
- myout << x << newline << y << newline ;
- myout.level--
-
- This class isn't perfect, but I hope you get the idea. More elaborate
- methods can be devised that put the newline detection in the
- streambuf and avoid newline. These also require downcasting so
- that you can be sure the streambuf is the right type before you tell
- it to change level.
-
- |> >
- |> >> Inother words, in a *domestic* system, any apparent
- |> >>need for downcasting should be used as an indicator of flawed design.
- |> >>
-
- indentstream can be done without derivation and without downcasting by use
- of the iword facility of streams, but that feature of streams is generally
- regarded as baroque and unappealing. It was included in the stream
- interface precisely because safe downcasting wasn't available.
- People frequently just go ahead and use an unsafe cast in "newline"
- (or its equivalent).
-
- -- Jerry Schwarz
-