Why Do I Need to Include Both the iOStream and Fstream Headers to Open a File

Why do I need to include both the iostream and fstream headers to open a file

You need to include fstream because that's where the definition of the ofstream class is.

You've kind of got this backwards: since ofstream derives from ostream, the fstream header includes the iostream header, so you could leave out iostream and it would still compile. But you can't leave out fstream because then you don't have a definition for ofstream.

Think about it this way. If I put this in a.h:

class A {
public:
A();
foo();
};

And then I make a class that derives from A in b.h:

#include <a.h>

class B : public A {
public:
B();
bar();
};

And then I want to write this program:

int main()
{
B b;
b.bar();

return 0;
}

Which file would I have to include? b.h obviously. How could I include only a.h and expect to have a definition for B?

Remember that in C and C++, include is literal. It literally pastes the contents of the included file where the include statement was. It's not like a higher-level statement of "give me everything in this family of classes".

Why include both iostream and fstream

std::ofstream is defined in <iostream>

Nope. It could be declared there, but it's defined in fstream.

Why would I include iostream and ostream separately?

Although stringstream inherits from iostream, it is not declared in the <iostream> header. The <iostream> header contains the definition of the iostream type along with the famous cout, cerr, cin, and clog types, but not other types that are iostreams (for example, file streams). For these, you do need to explicitly #include the requisite header files.

EDIT: In response to your revised question, I pulled up the C++ spec and interestingly it does not say that <iostream> has to include either <ostream> or <istream>. In fact, it could get away with just including <iosfwd>. Consequently, it's possible to #include <iostream> without actually getting a full class definition for either istream or ostream. Only explicitly including those headers can guarantee that the definitions of those classes, not just the forward-declarations, are visible.

When to include the string header in your program?

Your teacher was correct.

Your program worked without <string> by chance. Your standard library implementation, of that version, on that platform, under those circumstances, on that day, transitively included what you needed via <iostream>. The standard library is just code, like yours, and it just so happens that your particular implementation contains, inside <iostream>, an #include <string>. It could be buried behind many other #includes but got there eventually. But that's honestly pure chance, and does not mean that this is something the language guarantees, or something that must always be the case even in practice.

You should always code to standards.

If you're using features from <string>, include <string>.

Just today I was trying to build my big project with a new toolchain and found a few places where I'd accidentally relied on transitive includes, and it broke the build as a result because the new standard library implementation had a slightly different arrangement of headers. I dutifully added the missing #includes and now the world is a better place for it.

c++ header files (General Question about redundancy)

The general issue

The reason you have to include relevant headers in each .cpp file is because such .cpp files are compiled separately and independently; in more formal parlance: They constitute different "translation units". See also:

What is a "translation unit" in C++

Sometimes, when multiple translation units must all include several headers, we define a common single header file which containing all these inclusions - so that the .cpp files only need to include the common header to get all their necessary inclusions. Remember that inclusion is basically pasting the contents of the included file instead of the #include directive, and parsing that file as well, so an include-in-an-include is the same as making a direct #include.

Your specific example

In your specific example,

  • You actually don't need to #include <iostream> in second.cpp, because you only seem to be using constructs from <fstream>.
  • You don't need to #include <fstream> in any of the .cpp files, because they #include "second.h", which in turn includes <fstream> (so that it gets included when they are compiled, as well).

When should I `#include ios`, `#include iomanip`, etc.?

If I follow this rule religiously, will I ever run into a case where I need to include <ios>, <iosfwd>, <istream>, <ostream>, and/or <streambuf> in my application code?

Well, <iostream> includes <ios>, <streambuf>, <istream>, and <ostream>. And <iosfwd> are just forward declarations, so you don't really need that one either. So... I suppose, yes.

<fstream> gives you all the file-related stuff: filebuf, ifstream, ofstream, and fstream (and their wide counterparts).

<sstream> similarly gives you all the stringstream types and stringbuf.

All that leaves you with is remembering what's in <iomanip>, which isn't that much, but you could always just look it up.



Related Topics



Leave a reply



Submit