knutson@hsinchu.sw.mcc.com (Jim Knutson) (08/04/89)
What's the difference between the ++ operator overload functions in these two examples? The Lippman book (p. 197) prefers to define the function type to return a reference to the class while the Pohl book (p. 125) seems to prefer to return the class. Both seem to work equally well as both lvalue and rvalue. class counter { int count; public: counter() { count = 0; } counter(int c) { count = c; } counter& operator ++() { count++; return *this; } value() { return count; } }; class counter { int count; public: counter() { count = 0; } counter(int c) { count = c; } counter operator ++() { count++; return *this; } value() { return count; } }; Jim Knutson knutson@mcc.com cs.utexas.edu!milano!knutson -- Jim Knutson knutson@mcc.com cs.utexas.edu!milano!knutson
acw%illini@Sun.COM (Alex Wu [GPD] x6-6874) (08/05/89)
In article <2731@hsinchu.sw.mcc.com>, knutson@hsinchu.sw.mcc.com (Jim Knutson) writes: > What's the difference between the ++ operator overload functions in > these two examples? The Lippman book (p. 197) prefers to define the > function type to return a reference to the class while the Pohl book > (p. 125) seems to prefer to return the class. Both seem to work > equally well as both lvalue and rvalue. > > class counter { > int count; > public: > counter() { count = 0; } > counter(int c) { count = c; } > counter& operator ++() { count++; return *this; } > value() { return count; } > }; > > class counter { > int count; > public: > counter() { count = 0; } > counter(int c) { count = c; } > counter operator ++() { count++; return *this; } > value() { return count; } > }; > One difference I can think of is that the first class allows the cascade of "++" in this case, that is: counter i; (i++)++; cout << i.value() << '\n'; // gives 2 while the second one gives 1. Alex Wu Sun Microsystems, Inc. 415-336-6874 acw@sun.com
dog@cbnewsl.ATT.COM (edward.n.schiebel) (08/07/89)
From article <119611@sun.Eng.Sun.COM>, by acw%illini@Sun.COM (Alex Wu [GPD] x6-6874): >> these two examples? The Lippman book (p. 197) prefers to define the >> function type to return a reference to the class while the Pohl book >> (p. 125) seems to prefer to return the class. Both seem to work >> equally well as both lvalue and rvalue. >> ... > One difference I can think of is that the first class allows > the cascade of "++" in this case, that is: > > counter i; > (i++)++; Also: By returning a reference, the result may be used as an lvalue. (i++) = something else; If used on the right hand side of an assignment i.e. j = i++, return by reference (almost) guarantees a copy of the object is not created in the process. Ed Schiebel AT&T Bell Laboratories att!vilya!dog
dspoon@ncratl.Atlanta.NCR.COM (Dave Witherspoon) (08/07/89)
In article <2731@hsinchu.sw.mcc.com>, knutson@hsinchu.sw.mcc.com (Jim Knutson) writes: > What's the difference between the ++ operator overload functions in > these two examples? The Lippman book (p. 197) prefers to define the > function type to return a reference to the class while the Pohl book > (p. 125) seems to prefer to return the class. Both seem to work > equally well as both lvalue and rvalue. > > class counter { > int count; > public: > counter() { count = 0; } > counter(int c) { count = c; } > counter& operator ++() { count++; return *this; } > value() { return count; } > }; > > class counter { > int count; > public: > counter() { count = 0; } > counter(int c) { count = c; } > counter operator ++() { count++; return *this; } > value() { return count; } > }; I was recently puzzled by a very similar problem. There is definitely some reason to be cautious when returning values from operator overloads. The reason to be careful is that if you return a reference to an object allocated in the heap, then that object may never be destructed. For example, consider something like: ---------------------- class Frangis { private: int a; public: Frangis(int aa) {a=aa;} Frangis& operator+(Frangis &other_frangis); }; Frangis& Frangis::operator+(Frangis &other_frangis) { return new Frangis(a + other_frangis.a); } ----------------------- The result is created in the heap and is copied (via operator=) into the designated result variable you specify (or none). When the program terminates, any of these results from Frangis::operator+ will be left hanging around in the heap. Returning stack values from operator overloads has the benefit that all the space is returned automatically...the cost is more stack space consumed and additional work in copying the information. Returning a reference from an operator overload that affects "this object" seems to be OK...that object already exists so no temporary would be created for the return (methinks). To get a better understanding of how all this works, start with a very simple class (like Frangis, which by the way is an excellent word to use when you can't think of the right word) and overload its operator= (i.e., create your own instead of using the default). Also create one overloaded operator function (e.g., "=") that returns a ref to a Frangis and another (e.g., "-") that returns a Frangis. Using cout's in the Frangis constructor, destructor, oper=, oper+ and oper-, you should be able to watch objects come and go. If you can't account for all of them when the program terminates, you know "something's up". Hope this helps! -------------------------------David Witherspoon------------------------------- D.Witherspoon@Atlanta.NCR.COM | "Dolphins find humans amusing, but NCR Retail Systems Development/Atlanta| they don't want to talk to them." MY OPINIONS...ALL MINE!!! | - David Byrne