I am working on understanding streams, to better understand what happens when dealing with files, overloading of << and >> in C++.. If we have the following code (I have set in some comments). I am especially curious re. the overloading of the << operator. Like what exactly are we doing. I know the 'signature' of how to do it, and that we are overloading it to output self-defined types, but curious re. what exactly is happening inside the function body.
1 2 3 4 5
string p;
stringstream sp;
sp << "hellohello"; //inserts "hellohello" to the sp stringstream.
sp >> p; //extracts "hellohello" into p.
cout << "hello"; //inserts "hello" into the standard output stream (screen).
#include <iostream>
usingnamespace std;
class Date
{
int mo, da, yr;
public:
Date(int m, int d, int y)
{
mo = m; da = d; yr = y;
}
friend ostream& operator<<(ostream& os, const Date& dt);
};
ostream& operator<<(ostream& os, const Date& dt)
{
os << dt.mo << '/' << dt.da << '/' << dt.yr;
return os;
}
int main()
{
Date dt(5, 6, 92);
cout << dt;
}
That line by itself would have no meaning for a class date type. But in your class you overload the << operator and define what should happen. Now you can cout << dt and it means something.
I understand that, but what exactly are we doing within the operator overloading function. In the following line
1 2
os << dt.mo << '/' << dt.da << '/' << dt.yr;
what exactly are we doing. Are we inserting three ints into the os? I understand the 'result', but I am curious about what actually happens. And what exactly happens when we cout << dt?
Generates a sequence of characters with the representation of val, properly formatted according to the locale and other formatting settings selected in the stream, and inserts them into the output stream.
Internally, the function accesses the output sequence by first constructing a sentry object. Then (if good), it calls num_put::put (using the stream's selected locale) to perform both the formatting and the insertion operations, adjusting the stream's internal state flags accordingly. Finally, it destroys the sentry object before returning.
I'll try to be a bit more clear.. I'm not sure exactly what happens inside the function body when we do the overloading operation. What exactly happens when we have the following code, and then call cout << dt; from main.
Be aware that at ostream the << (bit shift to left) operator is merely an overloaded operator function.
os << dt.mo << '/' << dt.a << '/' << dt.yr;
is the same as os.operator<<(dt.mo).operator<<('/').operator<<(dt.a).operator<<('/').operator<<(dt.yr);
So that's the statement to what's the compiler do resolve. Consider that this statement will get evaluated from left to right.
What exactly happens when we have the following code, and then call cout << dt; from main.
Your overloaded function will get executed, whereby cout will be passed into the operator<<() function (as reference). cout is merely an object (instance) of class std::ostream, so it can be passed to your overloaded << function. But instead of cout, you could as good as this pass 'cerr' or 'clog' (or your own object of type ostream). At last, cout will returned to the caller. If there are several <<'s, it is used for the next << in chain.