Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!crdgw1!uunet!bywater!arnor!watson!blinn.watson.ibm.com!mittle From: mittle@blinn.watson.ibm.com (Josh Mittleman) Newsgroups: comp.lang.c++ Subject: Re: Can I make overloaded operator functions virtual? Message-ID: <1991Mar22.181007.18431@watson.ibm.com> Date: 22 Mar 91 18:10:07 GMT References: <1991Mar20.074256.334@csis.dit.csiro.au> <1991Mar21.184133.14506@watson.ibm.com> <1991Mar22.044801.26365@world.std.com> Sender: @watson.ibm.com Reply-To: mittle@ibm.com Distribution: usa Organization: IBM T. J. Watson Research Lines: 63 I wrote: > class Base > { > public: > virtual int operator==(const Base&); > }; > > > class Derived : public Base > { > public: > int operator==(const Derived&); > }; > > > We would really like Derived::operator== to match the virtual > Base::operator==, but we need to be able to treat the argument as a > Derived&. In article <1991Mar22.044801.26365@world.std.com> William M Miller writes: > No, you really *don't* want that. Allowing something like that would open a > major hole in the type system. Assuming Derived::operator==() actually did > override Base::operator==(), code like the following would be possible: > > Base b; > Derived d; > Base& br = d; > > if (br == b) ... > > Since "br" actually refers to a Derived object, the "==" invokes > Derived::operator==() -- but it passes a Base object as the argument instead > of the Derived object expected by Derived::operator==(). Boom! I don't see that this follows. I am suggesting extension to the way virtual invocation works. In your example, you are explicitly asking for Derived::operator==(Base&). At compile time, we accept this because it will always match something, i.e., Base::operator==(Base&). At run time, we check to see what the Base& really points to. If it happened to be a Base, then we would invoke Base::operator==(Base&). If it happens to be a Derived, we invoke Derived::operator==(Derived&). The programmer could also provide a member Derived::operator==(Base&), if he wanted to handle that case in a special way. To summarize: Derived d, e; Base b, c; Base &br1 = d, &br2 = e, &br3 = b, &br4 = c; Derived::operator==(Derived&) invoked by (d == e), (br1 == br2), (br1 == e), (d = br2) Derived::operator==(Base&) invoked by (d == b), (br1 == b), (d = br3), (br1 = br3) Base::operator==(Base&) invoked by (b == c), (b == d), (b == br1), (b = br3), (br3 = c), (br3 = d), (br3 = br1), (br3 = br4) I may be missing something, but I see neither ambiguity nor danger in this system.