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 #include
s 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 #include
s 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>
insecond.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
Visual Studio Debugger Error: Unable to Start Program Specified File Cannot Be Found
How to Initialize an Array of Struct in C++
Speed Accessing a Std::Vector by Iterator VS by Operator[]/Index
Handling Ssl_Shutdown Correctly
How to Control My Pc's Fan Speed Using C++ in Vista
Throwing C++ Exceptions Across Dll Boundaries
Why C++ Doesn't Support Named Parameter
Openal: How to Create Simple "Microphone Echo" Programm
Cmake Link Library Target Link Error
What Does Exactly the Warning Mean About Hidden Symbol Being Referenced by Dso
Explicit Type Conversion and Multiple Simple Type Specifiers
Should I Include Stddef.H or Cstddef for Size_T
Purpose of Perfect Forwarding for Callable Argument in Invocation Expression
How to Determine the Value of Socket Listen() Backlog Parameter
What Is the Simplest Way to Convert Char[] To/From Tchar[] in C/C++(Ms)
What Does the & (Ampersand) at the End of Member Function Signature Mean