6

I was trying to do:

std::ofstream outFile (fname, std::ios::binary);
//...
outFile.flush();
outFile.close();

which works fine. But when I try to combine the two lines since flush returns a reference:

outFile.flush().close();

It gives error saying:

error: ‘struct std::basic_ostream<char>’ has no member named ‘close’

Then I looked at the reference more carefully and found out it actually returns ostream instread of ofstream..

why is this the case? Is it a bug or designed?

SwiftMango
  • 15,092
  • 13
  • 71
  • 136
  • 2
    Because `flush` here is a member function inherited from `ostream` and `ofstream` didn't implement its own `flush`.. However I think returning an `ofstream` is a better choice. – starrify Feb 22 '14 at 07:26
  • 2
    You shouldn't need to flush if you're closing anyway. That's part of what close does. – KitsuneYMG Feb 22 '14 at 07:45
  • 2
    In addition to not flushing before closing, you can also consider not to explicitely close the ofstream. At least if the scope ends there, there won't be any difference (unless you want to reuse the same ofstream object with a different file). – stefan Feb 22 '14 at 07:56
  • 1
    @stefan agree on implicitly closing with scope; variables should be defined in the most minimal scope possible, also let the destructor do the work :) – nevelis Feb 22 '14 at 08:04

1 Answers1

6

This is by design.

ostream is a class that encompasses writing a sequence to an associated stream buffer, which is an abstract class that is in charge of writing and reading to something. That something could be anything; a file, the console, a socket, etc.

ofstream is really just a convenience class that extends an ostream to 'automatically' use a type of stream buffer that writes to a file, called a filebuf. The only functions provided by ofstream are open, is_open, and close; these are really just an easy interface to the file-specific functionality of the underlying filebuf stream buffer object.

If you really wanted, you could create an ostream that does the exact same thing as an ofstream. It just requires more code and isn't as pretty or explicit.

std::filebuf f;
f.open(fname, std::ios::binary);

std::ostream os(&f);
os.write("Hello world!", 12);
os.flush();

// Error! close() isn't part of the streambuf interface, it's specific to
// files.
os.close();

Basically, ofstream doesn't actually do any sort of writing, so it doesn't implement functions like flush and write. All of the writing is done via the ostream class, which manipulates an underlying streambuf class, whose job it is to make sure the data reaches it's intended location (i.e. a file).

Collin Dauphinee
  • 13,664
  • 1
  • 40
  • 71