Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!brutus.cs.uiuc.edu!lll-winken!uunet!microsoft!alonzo From: alonzo@microsoft.UUCP (Alonzo Gariepy) Newsgroups: comp.lang.c++ Subject: Re: Implementing virtual functions that return reference to self Keywords: virtual functions, derived classes, extended typechecking Message-ID: <7137@microsoft.UUCP> Date: 28 Jul 89 04:45:13 GMT References: <8975@thorin.cs.unc.edu> <7131@microsoft.UUCP> Reply-To: alonzo@microsoft.UUCP (Alonzo Gariepy) Organization: Microsoft Corp., Redmond WA Lines: 80 As further explanation of why you would want the notion of passing invocation class through inherited and virtual functions, I present the following examples. First, remember that (in the proposed scheme) This& Base::func(){...; return *this;} is defined to return a Base& when it is called with Base b; b.func(); // returns a Base& but a Derived& when it is inherited by class Derived and called with Derived d; d.func(); // returns a Derived& EXAMPLE ONE inherited function Let's say we have a class of object called Bar. These objects can be incremented with the += operator, but they have to be normalized first. We don't automatically normalize them in the += function, because it takes awhile, and we often know that a particular instance is already normalized. Bar bell; bell.normalize += 8; Now we also have a subclass called Nun. It contains some extra stuff that must also be incremented, so we redefine += to Nun& Nun::operator+=( int i ) { this->Bar::operator+=( i ); extra += i; return *this; } When we increment nuns we would like to use identical syntax without worrying about the return type of Bar::normalize() Nun foo; foo.normalize += 5; For this to correctly call Nun::operator+=(), the definition of normalize must be This& Bar::normalize() {...; return *this;} As it must be for the following to compile without a type error Nun& Nun::nunfunc() {..., return *this;} foo.normalize.nunfunc(); If normalize() was added after class Nun, or is later removed, the definition of class Nun remains unchanged. As it should be, normalize() is only relevant to Bar. EXAMPLE TWO virtual functions As the example stands, the operator+=() functions in classes Bar and Nun cannot be made virtual because they return different types. If class Nun and the += functions are redefined as virtual This& Bar::operator+=(int); virtual This& Nun::operator+=(int); then the following code compiles as indicated Nun nun; Bar& bar = nun; nun.normalize += 2; // OK. bar.normalize += 2; // OK. (bar += 2).normalize; // OK. (nun.normalize += 2).nunfunc; // OK. (bar.normalize += 2).nunfunc; // **error** makes no sense anyway Alonzo Gariepy // If Microsoft has an opinion, alonzo@microsoft // they didn't tell it to me.