Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!psuvax1!husc6!ginosko!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: <7184@microsoft.UUCP> Date: 31 Jul 89 08:34:49 GMT References: <8975@thorin.cs.unc.edu <7131@microsoft.UUCP> <7137@microsoft.UUCP> <9694@alice.UUCP> Reply-To: alonzo@microsoft.UUCP (Alonzo Gariepy) Organization: Microsoft Corp., Redmond WA Lines: 52 In article <9694@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes: >At first glance it may seem obvious that it should be possible >in C++ for a virtual function to return a reference to *this >without converting it to its base class. However, a closer look >brings second thoughts. For example: > > class X { > public: > virtual X& self() { return *this; } > }; > > class Y: public X { > public: > virtual Y& self() { return *this; } // illegal > }; > > X* xp; > >The reason the line marked `illegal' is illegal is because >if it were legal, then it would be impossible to know the >type of xp->self() at compilation time. Yes and no. It would be very poor programming practice indeed to expect xp->self() to return anything but an (X&). Even if xp points to a subclass of X, this expression must return the compile time type of the call. The whole point of polymorphism is that a call such as xp->self() is transparent in the code (compile time). But why can't yp->self() return a (Y&)? The actual case that everyone is using is: . This works very well whether or not the function is virtual or has been redefined in a subclass. It is an intelligent cast, no more. If you wish this semantic in a virtual function, all redefinitions of it share the same semantic. Give the semantic a type name (This&) and all the redefinitions share the same type. Subclasses can inherit the semantic without silly redirection functions. Given a function (or set of virtual functions) defined with this type, you can tell exactly what type will be returned at compile time. Now I can call a function Y::sumYfunc(Y&), y1.self().someYfunc(y2.someXfunc()); as long as self() and X::someXfunc() share the new semantic. My only question is whether it is worth putting more special purpose syntax into C++. On the other hand, why stop now? Alonzo Gariepy // If Microsoft has an opinion, alonzo@microsoft // they haven't told it to me.