Click to See Complete Forum and Search --> : Need some help w/ C++ operator overloading...
Energon
06-17-2001, 12:07 PM
I'm having some trouble getting a grasp on how to do operator overloading... here's what I got so far:
public:
/* overload = to set current buffer */
void operator=(const string buffer) { set_current_buffer(buffer); };
/* overload += to add to current buffer */
void operator+=(const string buffer) { add(buffer); };
/* overload << to print current buffer */
void operator<<(const string buffer) { print(buffer); };
/* overload >> to get current buffer */
void operator>>(string* out) const { *out=m_current_buffer; };
now, all the code I've seen for operator overloading, returns a reference to the class, which I don't really get... but the big thing is the operator>>() that I'm trying to overload... basically I'm trying to make it so someone can do something like they can w/ cin, where it takes a string value and puts it into the string it was given as a parameter... except in my case, I have a member variable, m_current_buffer, that I want to set the passed string to, but I can't for the life of me figure out how to do that... :(
thephunhouse
06-17-2001, 07:25 PM
Alot of times, operator<< and operator>> are defined as non-member (possibly friend) functions. Consider this example:
ostream& operator<<(ostream &o, const MyClass &m) {
o<< m.data;
return(o);
}
Using the overloaded operator is the same thing as making the function call with the full name. The above function could be called either way:
MyClass m;
cout<< m; //using operator notation
operator<<(cout, m); //using full func name
When you overload a binary operator as a member function of a class (like in your example), the calling instance of the class is the left hand side, and the single argument is the right. If this operator was defined as a member function, you would have to rewrite the call to it like this:
MyClass m;
m.operator<<(cout); //using fullname
m<< cout; //?!
Since this is a member function, the object name must be to the left of the function call. While this would still work, it makes for awkward syntax.
[ 17 June 2001: Message edited by: thephunhouse ]
Bradmont2
06-17-2001, 09:12 PM
Originally posted by thephunhouse:
<STRONG>Alot of times, operator<< and operator>> are defined as non-member (possibly friend) functions. </STRONG>
Errms... I was under the impression that they always were, and had to be. Is this not the case?
Energon
06-17-2001, 10:28 PM
:confused:
but, my operator>>() compiles and runs just fine... :confused:
sans-hubris
06-18-2001, 03:20 AM
I don't know exactly why your << and >> operators work. What compiler are you using?
As far as returning the object itself is concerned, it allows for cascading. E.g.:
//assume all the following objects are the same except str which is a string
cout << someObject << someOtherobject << str;
//or
thisObject=someObject+=someOtherObject + anotherObject;
Now, if the class of the objects above overloaded the += operator but didn't return an object of that class, the fourth line wouldn't work as expected even though it's a valid expression. If the << or >> operators didn't return the appropriate stream objects, the second line wouldn't work as expected.
[ 18 June 2001: Message edited by: ndogg.cpp ]
Stuka
06-18-2001, 10:54 AM
You can overload >> and << as member functions, but this limits their usefulness to places where the class object is the left hand side of the expression. If you create it as a friend function like so:friend ostream& operator<<(ostream& o, const MyClass& m); (and of course a version for >> also) you can then use your class in a long cin << foo << bar; type expression. If defined as a member function, you'll only be able to use it singly in a line. The reason for this, btw, is the way the expressions are evaluated - a void return value would screw up the chain of stream references needed to daisy-chain the input/output operations.
<edit>The way I like to think of operator overloading is just to think of the operator as a function call (which in this case it really is) with an argument list that goes left to right....it works for me, at least! :)</edit>
[ 18 June 2001: Message edited by: Stuka ]
Energon
06-18-2001, 01:44 PM
so, would that work out like this:
MyClass.h
class MyClass:
{
....
}
friend ....
or does the friend have to be in another class somewhere?
Stuka
06-18-2001, 01:55 PM
class MyClass {
...
...
friend ostream& operator<<(blah);
}
ostream& operator<<(blah){
}
You have to define it as a friend in your class, then define the function in whatever place is appropriate (generally your implementation file for the class).
dchidelf
06-18-2001, 01:58 PM
Overloading << and >> ....
When C++ was developed as an OO extension to C there were a few unfortunate side-effects.
Confusion being the primary of these.
Needing symbols to use for the iostreams the little used bit-shift operators were picked (<<, >> ). In C++ << is still a left bit-shift...and >> a right bit-shift...however somewhere amid the piles of headers and librarys (I believe in iostream.h) these operators are overloaded for a lefthand-side iostream... so whenever your program runs into :
cout << "stuff";
it calls:
ostream: :operator<<(char *)
or something of the like...
So a member function:
void operator<<(char *)
will work ... you are overloading the
left bit-shift operator...
you can do this:
int a = 3 << 1;
cout << a;
this should print 6 ...0000011 shifted 1 to the left ...000000110
bit-shifts work great for multiplication by 2...they are generally much faster than *2
To overload the ostream << operator the lvalue needs to be of type ostream...
a member overloaded operator function assumes an lvalue of the same type as the class...so the function must reside outside the class.
Making the function a friend will allow the function to access private members in the class...otherwise it must rely on public get, set functions.
Enough blabbering... :)
Chad
Energon
06-18-2001, 09:29 PM
Originally posted by dchidelf:
<STRONG>a member overloaded operator function assumes an lvalue of the same type as the class...so the function must reside outside the class.
</STRONG>
but why is that? You can create linked lists fine (ie, a Node class with a pointer to another Node and possibly a function to return that pointer)... so why does it have to be different here? Or is it somehow because you're returning a reference instead of a pointer?
Stuka
06-19-2001, 12:21 AM
Unlike normal functions, where you get to define the argument list in anyway you want, all binary operators assume the first argument to be the item on the left side of the operator, and the second to be on the right side. Because the first item passed to ANY member function in C++ is the this pointer, an overloaded operator declared as a member function MUST have the class member as its left hand value. When you overload a binary operator as a friend, you (the programmer) get to explicitly define which item is on which side of the operator by the order in which you declare your argument list. I hope that made sense....
sans-hubris
06-19-2001, 02:14 AM
Originally posted by Energon:
<STRONG>but why is that? You can create linked lists fine (ie, a Node class with a pointer to another Node and possibly a function to return that pointer)... so why does it have to be different here? Or is it somehow because you're returning a reference instead of a pointer?</STRONG>
That's part of our point. With a Node class, you would assume the left side of the operator is of the Node class. Take for example the = operator, it wouldn't exactly make sense to assign a Node to an int now would it?