Understanding streams

Hello,

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). 


And the

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace 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;
}
Last edited on
This has much to do with line 24. 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?
Last edited on
I'm not sure what you ask.

First, (unlikely) interpretation:
You are not sure what the following code does:
1
2
3
4
5
6
7
8
int mo = 4;
int da = 16;
int yr = 2019;
cout << mo;
cout << '/';
cout << da;
cout << '/';
cout << yr;


Second:
What does ostream& ostream::operator<< ( int ) do?

See: http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/
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.
1
2
3
4
5
ostream& operator<<(ostream& os, const Date& dt)
{
    os << dt.mo << '/' << dt.da << '/' << dt.yr;
    return os;
}


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.
Last edited on
So when we write
 
cout << dt;

the meaning is really
 
operator<<(cout,dt);


If we had an ofstream(also output stream) object instead, for example
1
2
3
4
ofstream ost{"filename.txt"};
//and wrote
ost << dt;
//the meaning is operator<<(ost,dt); 

and it is written to the file in the same format as it would be displayed on the screen..?
Correct. This works because ofstream is a subclass of ostream. That's a good example of how polymorphism works.
os << dt.mo << '/' << dt.da << '/' << dt.yr;

In this line, os is the name of your outstream.

This function returns the value of os, which contains...dt.mo << '/' << dt.da << '/' << dt.yr

So the result is like saying...

cout << dt.mo << '/' << dt.da << '/' << dt.yr;
Topic archived. No new replies allowed.