Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!ucsd!ucbvax!ulysses!allegra!fox From: fox@allegra.att.com (David Fox) Newsgroups: comp.lang.c++ Subject: Re: friend operator +(l,r) vs. operator +(r) Message-ID: Date: 28 Nov 90 14:21:50 GMT References: <11759@hubcap.clemson.edu> <1990Nov21.053431.22340@actrix.co.nz> Sender: netnews@ulysses.att.com Organization: AT&T Bell Laboratories Lines: 42 In-reply-to: glenn@huxley.huxley.bitstream.com's message of 27 Nov 90 23:11:42 GMT glenn@huxley.huxley.bitstream.com (Glenn P. Parker) writes: >fox@allegra.att.com (David Fox) writes: >> Another difference is that the member version can be virtual, while >> the friend version cannot. > Is this really a big difference? Global overloading can make operator+ >work very much like a virtual function. If the friend function is declared >as: > class A { > // ... > friend A operator+ (const A& left, const A& right); > }; > Then classes derived from A can use operator+ automatically, *or* they can >override it as follows: > class B : public A { > // ... > friend B operator+ (const B& left, const B& right); > }; With a virtual function the actual type of the object need not be known by the caller, only the base type. A function(A& left, A& right) // Suppose left was actually of type B& { return left + right; // Call the virtual member function operator+ } This will call B::operator+ if A::operator+ is virtual and B::operator+ exists (provided the arguments match). Of course, B::operator+ must then take account of the actual type of its argument, but this is easy since operator+ is commutative (isn't it? :-) A B::operator+(A& arg) { return arg + (*this); } This will call A::operator+(B&), or if this is virtual and arg is a B it will call B::operator+(B&). David Fox