Point 4 and Point 3
Starting with point 4 because everything else hinges on it and point 3 because it is tightly related.
When you flush the stream, you are taking all data stored by the stream and writing it to the underlying medium represented by the stream.
When it is flushed it is done, committed and ready to be observed by the outside world (More or less. The operating system and the hardware backing the stream may also delay the write, but there isn't much you can do about that). You can't read it until it has been flushed. If it's never flushed, you can't read it.
The thing is you do not want to write to IO very often because anything that goes out of the CPU takes an ungodly amount of time compared to that which stays inside the CPU. Tens of thousands of times slower sometimes. Inside the CPU you have gigahertz and parallel buses moving data 32 or more bits at a time. Outside you have megahertz often moving a single bit at a time.
Take a file as a classic example. Not only is drive access running at a fraction of a speed of the CPU, but if every byte goes directly to a disk, then for every byte you may have to
- find that byte's analogue on the disk.
- load the sector around that byte into memory. So instead of moving one byte, you may be moving a few hundred or thousand. Usually 512 bytes or 4096 bytes.
- write the byte into the sector in memory
- write the sector in memory back to the disk
Brutal. Imagine doing this a few hundred or a few thousand times to write a single string. But what if you only wrote the string when it got too big to hold or you were done? What if you wrote in sectors rather than bytes? Then you could
- find the sector on the disk.
- write the buffered sector to the disk
One operation for potentially thousands of byte in one shot.
Point 2
Point 2 goes back to point four/three's you can't read what you don't flush. If you want to see a particular output on the screen and you want to see it now, you flush. If you want to get a debug message out before the program crashes, and likely terminates without getting those last few absolutely essential messages onto the screen, you flush. History is full of programmers looking in the wrong place for a bug because they didn't get those last few unflushed error messages.
You are trading program speed for the relative certainty that you will see an important message when you need to see it.
Point 1
Point 1 calls back to point 2. std::endl is both an end of line and an instruction to flush the stream. You use it sparingly and only when you need both an end of line and a flush. If you don't need a flush, just send and end of line: '\n'.
Take Pete Becker's advice and use std::cerr for errors and debugging where possible. That's what it was built for. It operates on brute force and ignorance. It's painful. It's slow. And it almost always works.
std::cerrto begin with.'\n'.std::ostream& debug = std::cerr;- makes it easier to spot debug output.