Thread: operator overloading

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    92

    operator overloading

    hi, i have some idea about operator overloading . in fact i have practised one sample program for addition of complex number by overloading '+' operator. those were simple program to implement and understand.

    but i could not understand if it ususes strems . i have seen many codes that returns streams reference and also taking argument streams.

    something like.....

    ostream& operator<<(ostream& c,x& a) ---- // line 1

    or sometimes like....

    some_stream_reference & some_operator( some_stream_reference & , may_be_some_other_arguments)



    i stumble and feel uncomfortable when i see strem reference (like ostream& ) . what it means ? when i should use it ?


    in the complex number addition we wrote

    complex operator + (complex a, complex b) // its so simple !!

    but look // line 1 ...its returning a reference !!

    i see there is a some variation in this two approach . can anybody tell me in a simple way what is happening at the stream reference ?

    is it necessary to use reference only when comes about streams !!

    thanks
    blue_gene

  2. #2
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    No references aren't only for streams. You could also write:
    Code:
    const complex& operator + (const complex& a, const complex& b)
    Some would argue that it is better to do it with const references so you don't make a copy. When working with streams you pass a non-const reference because you want to modify the stream. For example, you want to output the data in your class. The only way to change an object passed into your function is if it is passed in by reference (as a reference or pointer). If you passed the stream in like you did the Complex object, then you'd get a copy of the stream and outputting wouldn't work.

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    My understanding is:

    Passing by reference is frequently faster (for large objects) that passing by value. If you don't want the values to change in the function then pass it by const reference.


    Returning by reference can allow you to chain things.

    if c1, c2, c3, c4 are all complex numbers then;

    c1 = c2 + c3; //works for your code but

    c1 = c2 + c3 + c4; //won't work for your code.

    for stream operators if you want to be able to do this:

    cin >> c1 >> c2 >> c3;

    or

    ofstream fout //etc
    fout << c1 << ' ' << c2 << ' ' << c3 << ' ' << c4;

    then you need the return a reference version. If you want to be able to do:

    fout << c1;
    fout << c2;
    fout << c3;

    then you don't need the reference version. The standard way to do stream operators is to make them chainable, but you don't have to do it that way if you don't want to.

  4. #4
    Registered User
    Join Date
    Dec 2003
    Posts
    92
    thanks jlou and elad ....i read ur explanation. you have explained well. i have got some more questions reading your material.

    questions are....
    >>If you passed the stream in like you did the Complex object, then you'd get a copy of the stream and outputting wouldn't work.

    so what ?
    inside the function we had something like.....

    complex temp;
    temp.real = a.real + b.real;
    temp.ima =a.img + b.img;
    return (temp)

    so the function will return the desired value as demanded by the caller i.e c= a+b


    why the same thing we can not do for streams ! can't we store it in a temp and return the temp like above.

    if you are talking abt performance and speed thats a different matter. but as such i will there be any objection if we follow the above approach for streams as well ?


    >>c1 = c2 + c3 + c4; // as there is 2 '+' ?


    >>The standard way to do stream operators is to make them chainable

    from your material i have to conclude that if i see there are chains or mutiple operators then i must use reference .

    well, its really vauge to me why and how & will tackle the problem which was not possible by simple and ordinary method.


    thanks for the quick response.

    i must go for sleep now.
    blue_gene

  5. #5
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Quote Originally Posted by elad
    c1 = c2 + c3 + c4; //won't work for your code.
    I believe that does work with his code, since it returns a Complex object. You do not need to use a reference with the Complex object to chain the operator. If you had returned void (which is allowed), then you would not be able to chain them.

  6. #6
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Quote Originally Posted by blue_gene
    why the same thing we can not do for streams ! can't we store it in a temp and return the temp like above.

    if you are talking abt performance and speed thats a different matter. but as such i will there be any objection if we follow the above approach for streams as well ?
    The reason is that you cannot just make a copy of an output stream. A stream is a very complex object (no pun intended). It does not have a copy constructor because you cannot simply make a copy of it safely. Try:
    Code:
    std::ostream newCout(std::cout);
    It doesn't work, and as I said above, if you don't pass by reference, you are making a copy. So in this case you have to use a reference.
    Quote Originally Posted by blue_gene
    if i see there are chains or mutiple operators then i must use reference .
    As I said above (before I read your post), I don't think this true. In general, it is a good idea to use a reference for efficiency reasons, but in this case it is not required.

    Besides, it is not any harder to use a reference. It's just a single extra character in a few places. It's well worth it to get into the good habit, and to understand why and when one way is better than another.

  7. #7
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    I cede to jlou's opinion with regard to chaining + operators using a return by value mechanism. He's right. I'm wrong.

    IN which case I then end up asking the same questions blue_gene does--why do you HAVE to pass a stream by reference?---whether passing as parameter or as return value.

    The next level of the onion apparently is also provided by jlou.

    Quote Originally Posted by jlou
    The reason is that you cannot just make a copy of an output stream....It does not have a copy constructor...
    Interesting. If streams don't have a copy constructor then obviously you can't create copies of them like you would need to to pass them by value and you have to pass them by reference. Fair enough. But it then begs the question--Why don't the stream classes have copy constructors?

    I suppose the creator of the language could have said "And thou, o stream, has failed me and therefore thou shalt not be allowed to be reproduced by coping whereas all others of my kindred shall not be so hindered". But I suspect there is a more earthly reason somewhere, that many of us haven't heard of (or haven't bothered to remember until now).

Popular pages Recent additions subscribe to a feed