From cplusplus.com, I saw that ostream
class's member function operator<<
looks like this:
ostream& operator<< (bool val); ostream& operator<< (int val);
.... and so on.
It does make sense because when you use the Cout object like cout<<x
you activate the ostream& operator<< (int val)
function, so you actually use the <<
operator on Cout object. This is very much like every other operator and sends the int
variable to the function. What is the difference and what exactly happens when I want to stream an object of my own? Why does the syntax is suddenly ostream& operator<< (**ostream &os**, object ob)
?
Why do I need to add the ostream
var? I am still using cout<<ob
so whay isnt it just ostream& operator<< (object obj)
? All I pass is my object. The cout
object is allready there.
operator<<
is generally defined as a free function; that is, not a member function. Since it is an overloaded binary operator, that means it get's its left argument first and its right argument second.
The operator<<
traditionally returns a reference to its left argument to enable the idiomatic chain of output.
To make it obvious to the reader, I tend to define my operator
overloads using the lhs
and rhs
abbreviations; an operator<<
would look similar to this, for some type T
.
std::ostream& operator<<(std::ostream& lhs, T const& rhs)
{
// TODO: Do something
return lhs;
}
As a member function
As with other binary it could be defined as a member function. That is, let us suppose that you with defining your own iostream
. Amongst other things, your class declaration may look like this. Again, T
is a particular type.
class MyIOStream : public iostream
{
public:
MyIOStream& operator<<(T const& rhs);
}
In this case operator<<
is a member function. It has the same semantics when used as <<
.
References
- Operators in C and C++ - a great summary of all the operators you can overload and their typical arguments.
why do I need to add the ostream var?
I'm sure it's there so that you can chain outputs together:
cout << foo << bar
The first call, cout << foo
will result in an ostream
reference that can be used for the << bar
part.
Some of the stream extractors are members of basic_istream
; because they are members, the basic_istream
argument is implied. Some of the stream extractors are not members of basic_istream
. Because they are not members, the basic_istream
argument has to be part of the declaration.
Like this (oversimplified):
class basic_istream {
public:
basic_istream& operator>>(int& i);
}
basic_istream& operator>>(basic_istream&, std::string& str);
Both can be called in the same way:
int i;
std::cin >> i; // calls basic_istream::operator>>(int&)
std::string str;
std::cin >> str; // calls operator>>(basic_istrea&, std::string&)