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.
Related
While following the book C++ For Dummies, I have three files in my CodeBlocks project, main.cpp, Pen.h, and Pen.cpp. They look like this:
main.cpp:
#include <iostream>
#include "Pen.h"
//#include "Pen.cpp"
using namespace std;
int main()
{
Pen MyPen = Pen();
MyPen.test();
}
Pen.h:
#ifndef PEN_H_INCLUDED
#define PEN_H_INCLUDED
//#include "Pen.cpp" // Uncommenting this gives a different error
using namespace std;
class Pen
{
public:
// attributes omitted
// PROTOTYPES:
// other functions omitted
void test();
};
#endif // PEN_H_INCLUDED
Pen.cpp:
#include <iostream>
#include "Pen.h"
using namespace std;
//other function definitions omitted
void Pen::test()
{
cout << "Test successful." << endl;
}
When I run the code as listed above, I get an "undefined reference to `Pen::test()'" error. To fix this, I changed the #include statements at the top of main.cpp to:
#include <iostream>
//#include "Pen.h"
#include "Pen.cpp"
This works as intended and correctly prints out "Test successful."
My question is this: what in the world is the point of putting a function prototype in a header file if I have to import the .cpp file later on anyways?
EDIT: It turns out this was a problem with not knowing how to use Code::Blocks rather than with the C++ language.
Assuming you're using gcc, you can compile and link in one step by supplying multiple .cpp files via the command line.
g++ Pen.cpp main.cpp
clang should be similar.
clang++ Pen.cpp main.cpp
An #include should never reference a .cpp file. At all. There's no good reason to do it. Include your headers and then supply the names of all .cpp files when you compile. If your project gets big and you have too many .cpp files to reasonably list, then it's time to break out a makefile or similar.
In the main.cpp include the header file:
#include "Pen.h"
The Pen.h file it's ok.
You need to add the Pen.cpp file to the project tree.
Go to Project -> Add files... and add Pen.cpp
I'm a bit confused at the moment because I'm planning to include multiple source and header files for the first time in one of my projects.
So I'm wondering if this would be the right approach?
Do I have to include the string header in every source file that uses it directly?
And what about the "stdafx.hpp" header that Visual C++ wants me to include?
Would that be the way to go?
main.cpp
#include "stdafx.hpp"
#include <string> //?
#include <stringLib1.h>
#include <stringLib2.h>
using std::string;
//use a windows.h function here
//use a stringLib1 function here
//use a stringLib2 function here
stringLib1.h
#include "stdafx.hpp"
#include <string>
using std::string;
class uselessClass1
{
public:
string GetStringBack1(string myString);
};
stringLib1.cpp
#include "stdafx.hpp"
string uselessClass1::GetStringBack1(string myString) {
return myString;
}
stringLib2.h
#include "stdafx.hpp"
#include <string>
using std::string;
class uselessClass2
{
public:
string GetStringBack2(string myString);
};
stringLib2.cpp
#include "stdafx.hpp"
string uselessClass2::GetStringBack2(string myString) {
return myString;
}
A good practice is usually to include only what your code uses in every file. That reduces dependencies on other headers and, on large projects, reduce compilation times (and also helps finding out what depends on what)
Use include guards in your header files
Don't import everything by polluting the global namespace, e.g.
using namespace std;
but rather qualify what you intend to use when you need it
You don't need stdafx.h in your project unless you're using precompiled headers. You can control this behavior in the VS project properties (C/C++ -> Precompiled Headers -> Precompiled Header)
The stdafx.h header is needed if precompiled header is enabled in VS. (Read this one)
You only need to include the stdafx.h in your .cpp files as the first include.
Regarding the header and cpp files (which come in pairs), include things necessary for the declaration in the header, and include everything else (necessary for the definition) in the cpp. Also include the corresponding header in its cpp pair too. And use include guards.
myclass.h
#ifndef MYCLASS_H // This is the include guard macro
#define MYCLASS_H
#include <string>
using namespace std;
class MyClass {
private:
string myString;
public:
MyClass(string s) {myString = s;}
string getString(void) {return myString;}
void generate();
}
myclass.cpp
#include <stdafx.h> // VS: Precompiled Header
// Include the header pair
#include "myclass.h" // With this one <string> gets included too
// Other stuff used internally
#include <vector>
#include <iostream>
void MyClass::generate() {
vector<string> myRandomStrings;
...
cout << "Done\n";
}
#endif
Then in main(...), you can just include myclass.h and call generate() function.
The stdafx include should be at the top of every .cpp file and it should NOT be in .h files.
You could put #include < string > in stdafx.h if you don't want to put it in every other file.
I suppose that you must be having your own header files also which might be requiring in other cpp files and header files. Like the one you gave
#include <stringLib1.h>
#include <stringLib2.h>
In my opinion, its better to create one common header file in which you include all the common library header files and your project header file. This file then you can include in all the other cpp files and header file. And it will be better to use header guards also.
So, considering a common header file "includes.h".
#ifndef INCLUDES_H
#define INCLUDES_H
#include <string>
#include <stringLib1.h>
#include <stringLib2.h>
/***Header files***/
#endif //INCLUDES_H
This is now your common header file. This you can include in all your project files.
Sorry. I'm somewhat new to building larger programs and linking files together and all that good stuff.
My function declarations in my header .h file have std::vector in them. Those function implementations in my header .cpp file also use std::vector. From my understanding, I should just use the "#include " in my header .h file because everything from that file will essentially be pasted into my header .cpp file at compile time. I'm just trying to make sure.
My .cpp file:
#include "PlagiarismDetector_Header.h"
// implementations of functions defined in PlagiarismDetector_Header.h
PlagiarismDetector_Header.h:
#include <iostream> // std::cout, std::endl
#include <vector> // std::vector
#include <string> // std::string
#include <algorithm> // std::swap
#include <math.h> // sqrt()
#include <set> // std::set
#include <map> // std::map
#include <fstream> // std::ifstream
std::vector<std::vector<std::string> > get_file_sntncs(std::fstream&);
std::vector<std::string> get_sntnc_wrds(const std::string&);
double sntnc_smlrty_qtnt(std::vector<std::string>, std::vector<std::string>);
// All the characters that constitute a word
const char LETTERS_ARR[] = {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'."};
const std::set<char> LETTERS_SET(LETTERS_ARR, LETTERS_ARR + sizeof(LETTERS_ARR)/sizeof(char));
You got it pretty much right but consider these aspects:
try to put an include guard in your header file since you may need to have it included twice in row in a future file
consider to push down to the implementation file(s) all constants and functions declarations that do not need to be exposed to the extern modules (whichever file including your header will see them even tough it does not need to use them)
if you use those constants in other files (that will include your header), follow john suggestion and make them extern
I'm doing the stanford course cs106b in C++, and I'm stuck and I can't seem to get it right. This probably a very easy fix for someone who knows this kind of stuff.
I have three files, one main.cpp and a randword.h and randword.cpp. In randword.h I have #include "simpio.h" which is a stanford library where GetLine() is defined. I can get GetLine() to work in the main.cpp file but when I try to compile I get "undefined reference to 'GetLine()'" in randword.cpp.
I use codeblocks and I have used the "Add files..." function.
Here's the code for main.cpp:
#include "randword.h"
/* Private function prototypes */
/* Main program */
randword rw;
int main() {
rw.initDictionary();
}
randword.h:
#ifndef RANDWORD_H_INCLUDED
#define RANDWORD_H_INCLUDED
#include <iostream>
#include <fstream>
#include <stdio.h>
#include "simpio.h"
#include "strutils.h"
using namespace std;
class randword{
public:
void initDictionary();
string chooseRandomWord();
string strArray[];
private:
};
#endif // RANDWORD_H_INCLUDED
random.cpp:
#include "randword.h"
using namespace std;
void randword::initDictionary(){
string fileName;
ifstream infile;
fileName = GetLine();
infile.open(fileName.c_str());
if(infile.fail()) cout << "Couldn't read file.";
return;
}
string randword::chooseRandomWord(){
string st1;
return st1;
}
Any help would be much appreciated! I suspect that this question was already posted, but I couldn't find it. Thanks!
try adding the library manually using code blocks
Open up your project
Right click your project and select build options..
select debugger
Go to linker settings
Under Link Librarys click "add"
Find your lib file, select it and keep as a relative path
Your project SHOULD run, if not reply here(as i explained something wrong)
randword.cpp does NOT have the library file needed to use GetLine, you may have included it inside your header file, but this does not carry over to randword.cpp. You need to include the library file just as you would in any other file in order to have access to it's functions.
//randword.cpp
#include <iostream>
#include "simpio.h" //include again!!!
//code here....
I'm trying to make a header file called hippiewh. However, I have been running into some problems.
here's the code for the header file:
#include <iostream>
#include <string>
using namespace std;
#ifndef hippiewh_h
#define hippiewh_h
int askInt(string prompt)
{
int var_int;
cout << prompt;
cin >> var_int;
return var_int;
}
#endif
there are functions like that one for every data type. string, float, and so on.
I can't get this header file working with the online IDE and compiler at Compilr.com
The error i'm getting is:
hippiewh.h: No such file or directory
Andrew, I bet you didn't write the include like this #include "hippiewh.h".
and you did it like this #include <hippiewh.h> which is wrong for your own created header files.
If you put all the code here we could help you
It should work without hassle :/
You must include the file this way
#include "hippiewh.h"