#include <sstream>
using namespace std;
int main()
{
cout << "hi"; // error: undeclared cout
}
From what I have read, sstream class is derived from iostream class but why does it not get included automatically?
The iostream-based classes are not the same as the iostream header. Standard headers do not have to include each other, or may include each other in any order. If you wish to use the contents of <iostream>, you must #include <iostream>.
std::sstream is derived from both std::istream and std::ostream. That means you don't need to include <istream> or <ostream>. However, std::cout is defined in neither of those two headers. That's why you need yet another header, <iostream>.
Related
I am new to c++ so forgive me if this question doesn't make much sense, but I have the follow files:
// main.cpp
#include <iostream>
#include <fstream>
using namespace std;
#include "second.h"
int main () {
string filename;
cin >> filename;
ifstream fileIn;
if( !openFile(fileIn, filename) ) {
cerr << "Could not open file \"" << filename << "\"" << endl;
cerr << "Shutting down" << endl;
return -1;
}
return 0;
}
// second.h
#include <string>
#include <fstream>
bool openFile(ifstream& inFile, string filename);
// second.cpp
#include "second.h"
#include <iostream>
#include <fstream>
using namespace std;
bool openFile(ifstream& inFile, string filename) {
inFile.open(filename);
if (inFile.fail()) {
return false;
}
return true;
}
My question is, why does c++ need so much redundancy?
Why do I need to #include <iostream> and <fstream> for both main.cpp and second.cpp if main already calls them? Why does the header files also need to include the function parameters (ifstream& inFile, string filename)? This just seems like a waste, when the function in second.cpp already asks for it. Why not just say openFile(); in the header and have function in second.cpp as for the parameters? This may just be more of a rant, but I just want a deeper understanding as to why theses redundancies are needed. Or is there something I am missing?
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).
You can include #include <iostream> and <fstream> into second.h and then include it to main.cpp. Don't forget to use Include Guard, when you link to header files.
main.cpp uses std::ifstream, std::cin, and std::cerr, this is why your example requires the includes in main.cpp.
You should
read about #include directive to understand this idea and what's going on during compilation.
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream myfile;
myfile.open ("test.txt");
return 0;
}
fstream is derived from iostream, why should we include both in the code above?
I removed fstream, however, there is an error with ofstream. My question is ofstream is derived from ostream, why fstream is needed to make it compile?
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".
std::ofstream is defined in the <fstream> standard library header.
You need to include that header for its definition so that you can instantiate it.
The typedef ofstream and its associated class template are defined by #include <fstream> , so you need that header.
For your actual program, #include <iostream> is not needed. But you may wish to use your fstream object with some functions which operate on ostream or istreams .
Those functions are not defined by #include <fstream> and you need to include the right header for any functions you do use. Some implementations might cause #include <fstream> to also include <iostream> but this is not guaranteed by the C++ Standard.
For example, this code:
ofstream myfile;
myfile.open ("test.txt");
myfile << 1;
requires #include <ostream> (or , since C++11, #include <iostream> which is guaranteed to bring in #include <ostream>).
I created this code:
Main.cpp
#include <iostream>
#include "Quote.h"
int main()
{
derived().print(std::cout);
getchar();
return 0;
}
Quote.h
#pragma once
#include <string>
class base {
public:
std::string name() { return basename; }
virtual void print(std::ostream &os) { os << basename; }
private:
std::string basename = "abc";
};
class derived : public base {
public:
void print(std::ostream &os) { base::print(os); os << " " << i; }
private:
int i = 0;
};
If I don't include the iostream header file in Main.cpp, as expected, std::cout is not recognized. My question is: Why there's no problem with the use of std::ostream in Quote.h if iostream is not included?. Either cout as ostream are defined in the aforementioned library, why the cout use is a problem and ostream not?
I'm using VS 2017, in case this info is important.
All existing answers concentrate on #include <string>. I'd like to point at another side. Consider slightly modified version:
quote.h:
#pragma once
// uncomment to get an analog of original example
// #include <string>
struct Quote {};
std::ostream& operator<<(std::ostream& os, Quote const&)
{
return os << "quote\n";
}
main.cpp:
#include <iostream>
#include "quote.h"
int main()
{
std::cout << Quote{};
}
As you see #include <string> is commented out, quote.h still doesn't include iostream and the program still compiles. It does because only source files (.cpp, or translation units) are directly compiled. Headers are literally included. Now if we literally include quote.h in main.cpp we get:
#include <iostream>
// uncomment to get an analog of original example
// #include <string>
struct Quote {};
std::ostream& operator<<(std::ostream& os, Quote const&)
{
return os << "quote\n";
}
int main()
{
std::cout << Quote{};
}
(online)
It's what actually gets compiled. Notice everything is alright here, #include <iostream> before std::ostream usage.
And as was correctly pointed in comment to another answer, this is an example why it's important to always maintain self-sufficient headers that include all headers they depend on.
As #Evgeny pointed out in the comment, please check recommendations about organising our includes.
The header <string> declares an output operator using std::ostream. It seems the implementation you are using does so in a way making std::ostream generally available.
The C++ standard defines which headers make which declarations available at least. It doesn’t prohibit against additional names being made available. Different implementations may choose to not make the declarations available. I have tried making strictly only mandated declarations available in my implementation but this turns out to be not quite as simple as it sounds.
You include <string> in your header file. If you go to the string header you will see the first lines as (in VS2017):
// string standard header
#pragma once
#ifndef _STRING_
#define _STRING_
#ifndef RC_INVOKED
#include <istream> <----- here
#include <xstring_insert.h>
and going to the istream header:
// istream standard header
#pragma once
#ifndef _ISTREAM_
#define _ISTREAM_
#ifndef RC_INVOKED
#include <ostream> <-- here
which I think already answers your question. However, this is implementation dependent and you should not rely on this but include explicitly the iostream header.
The header <string> provides the extraction and insertion operators for std::string, so it has to make sure that std::ostream is at least forward-declared; your code only uses a reference to ostream, for which a forward declaration suffices, plus the aforementioned insertion operator, which is correctly declared.
So, strictly speaking, all that is needed by your header is already provided by the header <string>, although I'd probably explicitly include <iosfwd> for clarity.
Why there's no problem with the use of std::ostream in Quote.h if <iostream> is not included?
<iostream> get #included indirectly.
It's best not to rely on such indirection #includes. You can't count on it being true on all platforms. It may even change from debug build to release build.
When you want to use a class or a function, it's best to lookup the standard for the header that's supposed to provide the definition of the class and the declaration of the function, and #include the header directly in your file.
I was splitting up my program into a header and implementation file per usual, however, when I tried to run the code, I got a ton of compile errors. This seems to be an issue with my computer or IDE, but I have not seen it before. This should be relatively simple as it is for a class project.
The code is as follows:
colorPicker.h
#pragma once
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
colorPicker.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
colorPicker::colorPicker() {
colorArray[0] = "Red";
colorArray[1] = "Green";
colorArray[2] = "Purple";
colorArray[3] = "Yellow";
colorArray[4] = "Orange";
colorArray[5] = "Indigo";
colorArray[6] = "Pink";
}
void colorPicker::printAllColors() {
for (int i = 0; i < 7; i++) {
cout << colorArray[i] << endl;
}
}
string colorPicker::randomColor() {
srand((unsigned)time(0));
int j = 0;
j = rand() % 7;
return colorArray[j];
}
main.cpp
#include "colorPicker.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
colorPicker p;
p.printAllColors();
cout << "Random Color: " << p.randomColor() << endl;
system("pause");
return 0;
}
There are 20 errors given by the compiler, however, they all seem to be stemming from two undeclared identifiers which are most definitely declared. I am at a loss for what I could possibly do to fix it, and this project is due Sunday. Thank you.
Here are the errors
Tons of Errors
You need #include "colorPicker.h" in colorPicker.cpp. Each .cpp file is handled basically independently by the compiler and they are all joined at the end by the "linker." When the compiler looks at colorPicker.cpp without an include of the corresponding header, it's at a loss as to the definition of all the classes you're working with.
There are a few things you are doing wrong. I'll just pick on a couple.
Firstly, each header file you write should be self-contained - in the sense that, if it relies on content of some other headers, it includes that header. If a compilation unit (a formal name for a source file with a .cpp in your case) includes your header, it should not have to include something else your header depends on.
Second, it is a bad idea for a header to rely on any using directive, such as using namespace std. There are plenty of explanations of that available, so I won't repeat.
To understand the above, look at colorPicker.h
class colorPicker {
private:
string colorArray[7];
public:
colorPicker();
void printAllColors();
string randomColor();
};
Firstly, this depends on string, but there is no definition of string visible in the header file. Usage of that type depends on the standard header <string>.
Second, that string type is within namespace std. So your header relies on the compilation unit (the source file that includes your header) having previously used a using directive i.e. using namespace std.
To fix these two problems, change the header to
#ifndef SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#define SOME_MACRO_UNIQUE_TO_YOUR_COLOR_PICKER_HEADER
#include <string>
class colorPicker
{
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
(I've also done some minor changes of layout, since I have various reasons to prefer that.
However, the #include <string> means that this version will not fail to compile, as yours does, if it is included by a compilation unit that does not have #include <string>.
The usage of the fully qualified name std::string, rather than string, also means there is no dependence on the using directive using namespace std. It also means compilation errors can't be triggered in your header if your compilation unit has another using directive.
I've also used an include guard, rather than #pragma once. Although most modern compilers support #pragma once, it is actually not standard C++ (a #pragma, by definition in the standard, is a compiler-specific hook). Include guards are supported in standard C++.
If you've done that, your code should mostly compile as is. However, optionally, you may wish to
remove the using directives using namespace std from your other files. If you do that, you will need to change the definition of colorPicker::randomColor() in colorPicker.cpp so it returns the fully qualified type std::string rather than string.
Remove #include <string> from files that have #include "colorPicker.h". This is possible, since colorPicker.h now includes <string>. This step is optional, since there is no problem with including standard headers more than once in a compilation unit.
A few other notes
In C++, although it is not a major concern, it is usually considered better to use include <cstdio> and <cstdlib> rather than the C headers <stdio.h> and <stdlib.h>.
Your code is calling srand((unsigned)time(0)) whenever colorPicker::randomColor() is called. It is better to only call it once in an entire program, not in a function that may be called multiple times.
A header file should be self-contained as far as #includes go. That means that you should be able to #include the header file without having to include other stuff before it!
Your colorPicker.h does not meet that requirement. It apparently uses std::string from the standard library but does not have an #include <string> on top, so everyone who uses colorPicker.h has to remember to put an #include <string> before it. That's pretty annoying.
Even worse, colorPicker.h refers to std::string as string, which implies a using std::string; or using namespace std; somewhere before any #include "colorPicker.h" line, and both of those are very bad coding style in C++, if not used in tighter scopes.
Here's how to fix the header file:
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
As far as your *.cpp files go, I can see that you are using #include "stdafx.h". Why? It's a non-standard Microsoft thing completely unnecessary in your case. You are also using it incorrectly. It must be the first include. Just remove it entirely.
Some other suggested cleanup:
using namespace std; lines in *.cpp files is not as bad as in header files, but if I were you, I'd just get rid of it completely. Just use complete names. Say std::cout, not cout. And so on. It's just the most consistent way and it avoids a lot of trouble.
You include a lot of headers which you don't need. For example, what's <ctime> for?
Don't use system("pause");. Do not look for artificial ways of pausing a command-line program.
You may need add head file and in colorPicker.h.
And the std namespace is needed while using string.
BTW, the header guards is recommended strongly.
#ifndef COLOR_PICKER_H
#define COLOR_PICKER_H
#pragma once
#include <string>
class colorPicker {
private:
std::string colorArray[7];
public:
colorPicker();
void printAllColors();
std::string randomColor();
};
#endif
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream myfile;
myfile.open ("test.txt");
return 0;
}
fstream is derived from iostream, why should we include both in the code above?
I removed fstream, however, there is an error with ofstream. My question is ofstream is derived from ostream, why fstream is needed to make it compile?
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".
std::ofstream is defined in the <fstream> standard library header.
You need to include that header for its definition so that you can instantiate it.
The typedef ofstream and its associated class template are defined by #include <fstream> , so you need that header.
For your actual program, #include <iostream> is not needed. But you may wish to use your fstream object with some functions which operate on ostream or istreams .
Those functions are not defined by #include <fstream> and you need to include the right header for any functions you do use. Some implementations might cause #include <fstream> to also include <iostream> but this is not guaranteed by the C++ Standard.
For example, this code:
ofstream myfile;
myfile.open ("test.txt");
myfile << 1;
requires #include <ostream> (or , since C++11, #include <iostream> which is guaranteed to bring in #include <ostream>).