Haiyuan Zhang
Haiyuan Zhang

Reputation: 42842

Where "include" in C++

I'm reading some C++ code and notice that there are "#include" both in the header (.hpp) files and source (.cpp) files. I guess if I move all the "#include" in the file, "foo.cpp", to its' header file "foo.hpp". Then let "foo.cpp" only one line of #include "foo.hpp", the code should work anyway taking no account of issues like drawbacks, efficiency, and etc .

I guess that my "all of sudden" idea must be in some way bad, but what could be the exact drawbacks of it? I'm new to C++, and I may need to read lots of C++ reference books to figure out.

Thanks in advance.

Upvotes: 33

Views: 25397

Answers (9)

jkp
jkp

Reputation: 81300

As a rule, put your includes in the .cpp files when you can, and only in the .h files when that is not possible.

You can use forward declarations to remove the need to include headers from other headers in many cases: this can help reduce compilation time which can become a big issue as your project grows. This is a good habit to get into early on because trying to sort it out at a later date (when its already a problem) can be a complete nightmare.

The exception to this rule is templated classes (or functions): in order to use them you need to see the full definition, which usually means putting them in a header file.

Upvotes: 41

Liz Albin
Liz Albin

Reputation: 1499

While a header file should include only what it needs, "what it needs" is more fluid than you might think, and is dependent on the purpose to which you put the header. What I mean by this is that some headers are actually interface documents for libraries or other code. In those cases, the headers must include (and probably #include) everything another developer will need in order to correctly use your library.

Upvotes: 2

Hans Passant
Hans Passant

Reputation: 942267

There's nothing wrong with using #include in a header file. It is a very common practice, you don't want to burden a user a library with also remembering what other obscure headers are needed.

A standard example is #include <vector>. Gets you the vector class. And a raft of internal CRT header files that are needed to compile the vector class properly, stuff you really don't need nor want to know about.

Upvotes: 1

jfawcett
jfawcett

Reputation: 895

The include files in a header should only be those necessary to support that header. For example, if your header declares a vector, you should include vector, but there's no reason to include string. You should be able to have an empty program that only includes that single header file and will compile.

Within the source code, you need includes for everything you call, of course. If none of your headers required iostream but you needed it for the actual source, it should be included separately.

Include file pollution is, in my opinion, one of the worst forms of code rot.

edit: Heh. Looks like the parser eats the > and < symbols.

Upvotes: 15

Arthur Kalliokoski
Arthur Kalliokoski

Reputation: 1647

You can avoid multiple definition errors if you use "include guards".

(begin myheader.h)
#ifndef _myheader_h_
#define _myheader_h_
struct blah {};
extern int whatsit;
#endif //_myheader_h_

Now if you #include "myheader.h" in other header files, it'll only get included once (due to _myheader_h_ being defined). I believe MSVC has a "#pragma once" with the equivalent functionality.

Upvotes: 0

anon
anon

Reputation:

If you #include the .cpp files, you will probably end up with loads of "multiple definition" errors from the linker. You can in theory #include everything into a single translation unit, but that also means that everything must be re-built every time you make a change to a single file. For real-world projects, that is unacceptable, which is why we have linkers and tools like make.

Upvotes: 1

Tyler McHenry
Tyler McHenry

Reputation: 76750

.hh (or .h) files are supposed to be for declarations.

.cpp (or .cc) files are supposed to be for definitions and implementations.

Realize first that an #include statement is literal. #include "foo.h" literally copies the contents of foo.h and pastes it where the include directive is in the other file.

The idea is that some other files bar.cpp and baz.cpp might want to make use of some code that exists in foo.cc. The way to do that, normally, would be for bar.cpp and baz.cpp to #include "foo.h" to get the declarations of the functions or classes that they wanted to use, and then at link time, the linker would hook up these uses in bar.cpp and baz.cpp to the implementations in foo.cpp (that's the whole point of the linker).

If you put everything in foo.h and tried to do this, you would have a problem. Say that foo.h declares a function called doFoo(). If the definition (code for) this function is in foo.cc, that's fine. But if the code for doFoo() is moved into foo.h, and then you include foo.h inside foo.cpp, bar.cpp and baz.cpp, there are now three definitions for a function named doFoo(), and your linker will complain because you are not allowed to have more than one thing with the same name in the same scope.

Upvotes: 1

P&#233;ter T&#246;r&#246;k
P&#233;ter T&#246;r&#246;k

Reputation: 116306

You would make all other files including your header file transitively include all the #includes in your header too.

In C++ (as in C) #include is handled by the preprocessor by simply inserting all the text in the #included file in place of the #include statement. So with lots of #includes you can literally boast the size of your compilable file to hundreds of kilobytes - and the compiler needs to parse all this for every single file. Note that the same file included in different places must be reparsed again in every single place where it is #included! This can slow down the compilation to a crawl.

If you need to declare (but not define) things in your header, use forward declaration instead of #includes.

Upvotes: 7

Paul
Paul

Reputation: 91

Including header files from within header files is fine, so is including in c++ files, however, to minimize build times it is generally preferable to avoid including a header file from within another header unless absolutely necessary especially if many c++ files include the same header.

Upvotes: 1

Related Questions