Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!hplabs!hp-pcd!hplsla!jima From: jima@hplsla.HP.COM (Jim Adcock) Newsgroups: comp.lang.c++ Subject: Re: Implementing virtual functions that return reference to self Message-ID: <6590220@hplsla.HP.COM> Date: 31 Jul 89 18:19:51 GMT References: <8975@thorin.cs.unc.edu> Organization: HP Lake Stevens, WA Lines: 59 >/ hplsla:comp.lang.c++ / dlw@odi.com (Dan Weinreb) / 1:17 pm Jul 27, 1989 / >In article <8975@thorin.cs.unc.edu> kelleymt@luther.cs.unc.edu (Michael T. Kelley) writes: > > In this case, I know I'm dealing with a Derived, so I'd like to be able > to use goodbye(). Can someone explain the harm in allowing hello() > to return a Derived& in the Derived class? Or is there an > implementation issue lurking underneath? > >My colleagues and I have seen this problem several times, in slightly >different guises. As far as we can tell, there is no good solution; >you have to use explicit casts. In my experience so far with C++, >this is the biggest problem caused by C++'s mixture of run-time and >compile-time type checking. (More accurately, its mixture of >run-time-polymorphic objects and typed variables.) There's no such >problem in languages like Smalltalk-80 and Lisp/CLOS, in which >variables are untyped. (I recognize that typed variables have >advantages too, and I'm not trying to provoke a general discussion of >the virtues and drawbacks of typed variables!) I believe there is such an issue in Smalltalk-like languages, its just resolved in a different manner. In Smalltalk-like [untyped] languages there is no compile-time check of the sanity of a particular method name being applied to a particular object. Since there are no types, there is no type checking, and the compiler simply allows it. Thus the sanity of applying a particular method name to a particular object must be checked manually by the programmer, and if a mistake is made, it is only detected as a run-time bomb. A typical problem is to send a message to an object that doesn't understand that message, or does understand it, but understands it to mean something different than you meant. This happens frequently on large projects where hundreds of message names are created weekly. Joe and Susan independently give their methods the same name, though they have different meanings. You typically don't find this out until a couple months later on the project, when Jack tries to access both Joe and Susan's objects in a uniform manner. C++ is a typed language, and thus squawks at compile-time if you apply a method name to an object in what seems to not be a sane manner. You coerce the object to apply any necessary transformations to make the object/method-name combo sane, or to tell the compiler you really do know what you're doing after all. So I see this as an issue of permissive compiler design verses safe compiler design. >The underlying philosophical problem is that d.hello().goodbye(); is >doing something that is perfectly meaningful, but the C++ compile-time >type checking system cannot prove in advance that the code meaningful, >so the compiler must tag the code as an error. You have to put in an >explicit cast into the code in order to assert to C++ that >everything's really all legal. Agreed. ....If you want to take a Smalltalk-like "untyped" approach to a portion of your code, derive from a specific base class, make virtual function templates, always return references to objects of that base type, and you have a Smalltalk-like approach. Almost no type checking. I don't recommend this, though. Type-checking helps verify the sanity of your coding, and can lead to much faster code.