luigi
luigi

Reputation: 160

Operator overload doubts

I was trying to write some operator overload functions, especially the << operator to use it with a custom class and an std::ofstream object, but I was a bit confused by the syntax used in various examples found online. For example, let's consider the operator<< overload as a non-member function for a simple custom class:

#include <fstream>

class Example {
public:
    int first;
    int second;
};

// I found this kind of operator on the Internet
std::ofstream& operator<< (std::ofstream& out, Example obj) {
    out << obj.first << endl << obj.second;
    return out;
}

int main() {
    Example a={1,2};
    std::ofstream out;
    out.open("test");
    out << a;
    out.close();   
}

I don't really get why It should return std::ofstream& to work properly. I tried using the following operator

void operator<< (std::ofstream& out, Example obj) {
     out << obj.first << endl << obj.second << endl;
}

and it worked as well. I mean, can't out << obj; be interpreted as operator<< (out , obj); ? Why does it have to return something since I'm passing a reference to the std::ofstream object?

The same doubt arose when I was trying to write an operator= overload as a member function for a custom class, as the simple example that follows

class Custom{
public:
    int up;
    int down;

    Custom& operator= (Custom a) {
         up=a.up;
         down=a.down;
         return *this;
    }
};

I used the copy-swap idiom for the assignment operator, so don't mind the operator definition too much, it's just an example. Again, writing

Custom obj1, obj2;
obj1 = obj2;

since I can interpret obj1 = obj2; as obj1.operator=(obj2), why is the return type Custom& required instead of void?

Upvotes: 1

Views: 96

Answers (4)

LogicStuff
LogicStuff

Reputation: 19607

If you want to be able to chain operator<<s together, you have to use a return type (better std::ostream& than std::ofstream&, so you can use it for std::cout and like, too).

out << a << b;
(out << a) << b;
^^^^^^^^^^
lhs has to be a stream

For assignment operator, the reason is essentially the same. C++ syntax allows you to write many expressions requiring the return type, for example this:

Custom obj1, obj2, obj3;
(obj1 = obj2) + obj3 ... // assign obj2 to obj1 and work with that...

Upvotes: 2

Semyon Burov
Semyon Burov

Reputation: 1172

You can write somthing like cout << "First operand" << "Second operand" because first operand returns reference to ostream and second operand works with this reference. operator= works same way. You can write a = b = c, but also you can put it inside if (a = b) or while (a = b). This can make your code shorter, but is a little dangerous.

Upvotes: 1

songyuanyao
songyuanyao

Reputation: 172924

Return a reference instead of void, make it possible to write like

out << obj1 << obj2 << obj3;

For operator=, you can write

obj1=obj2=obj3;

Upvotes: 1

Bo Persson
Bo Persson

Reputation: 92261

Returning a reference allows you to chain the operators, like

std::cout << e1 << e2;

Upvotes: 1

Related Questions