5

I want to print out an object of a user-defined type, like this cout << ob1; so I want to overload operator<< and I want to return by value not by reference but it gives me an error: in two files named : iosfwd and ios_base.h

ostream operator<<( ostream& out, cat& rhs){
    out << rhs.a << ", " << rhs.b << endl;
    return out ; 
}

1)Is it because it can't create a new ostream object, this is why it have to return by reference ?

but when I return by reference like this :

ostream& operator<<( ostream& out, cat& rhs){
    out << rhs.a << ", " << rhs.b << endl;
    return out ;
}

it works fine.
2)any explanation ?

AlexDan
  • 3,203
  • 7
  • 30
  • 46
  • What error message do you get? – orlp Mar 10 '12 at 13:42
  • 2
    Also, why would you want to return by value? – r_ahlskog Mar 10 '12 at 13:48
  • A side note, using endl in your operator makes outputting your type (unexpectedly) flush the iostream. You may want to skip it, or if you _really_ want to output to several lines, output a '\n' instead. – Joachim Isaksson Mar 10 '12 at 13:54
  • @JoachimIsaksson I guess the endl object will work fine, since I did not overload operator<< for type of endl object . no ? – AlexDan Mar 10 '12 at 13:59
  • @AlexDan Yes, there's no problem with using it more than that endl does not just output a line feed, it also flushes the stream which takes quite a bit more time. – Joachim Isaksson Mar 10 '12 at 14:03

3 Answers3

17

In the first example, you return a copy of the stream object which is not allowed because the copy-constructors (and copy-assignment as well) of all the stream classes in C++ has been disabled by having them made private.

Since you cannot make a copy of a stream object, you're required to return it by reference, which you're doing in the second example which is why it is working fine.

You may choose to return nothing at all (i.e you can make the return type void), but if you do so, then you would not be able to chain as stream << a << b. You've to write them separately as stream <<a and then stream << b.

If you want to know why copying of stream objects is disabled, see my answer here:

Uncertainly Certain
  • 357
  • 1
  • 4
  • 14
Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

Streams are non copyable because copying a stream doesn't really make sense, a stream is unique (you can't jump in the same river twice kind of thing). return by value is in C++03 at least copying transaction.

If there are reason you want to return by value, return by reference is the correct version.

111111
  • 15,686
  • 6
  • 47
  • 62
0

It is done to support safe and reasonable operator chaining like

    cout<<a<<b;  

works because of returning a reference.

DotNetUser
  • 6,494
  • 1
  • 25
  • 27