tags:

views:

381

answers:

9

I'm reading some c++ code and Notice that there are "#include" both in the header files and .cpp files . I guess if I move all the "#include" in the file, let's say foo.cpp, too its' header file foo.hh and let foo.cpp only include foo.hh the code should work anyway taking no account of issues like drawbacks , efficiency and etc .

I know my "all of sudden" idea must be in some way a bad idea, but what is the exact drawbacks of it? I'm new to c++ so I don't want to read lots of C++ book before I can answer this question by myself. so just drop the question here for your help . thanks in advance.

+1  A: 

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.

Péter Török
Or, more correctly, use forward declaration instead of `#include` in your .h files whenever you can. Sometimes it's unavoidable. For example, if class A has a data member of class B, then A.h will have to include B.h.
David Thornley
+9  A: 

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. In C++0x we will finally get a way to declare "extern templates" meaning we can hide the definitions in other source files and the linker will know where to find them.

jkp
"this can help reduce compiliation speed" -- I think you mean time, not speed. :)
carl
@cvondrick: good find :) thanks.
jkp
Your interpretation of "extern template" is very wishful thinking. You'll be disappointed.
Hans Passant
@nobugz: Oh? really? Goddam it I hope it's not...template compilation speed is one of the worst things about C++. Being able to hide the implementations from those who don't need to see them would be a real boon.
jkp
@jkp: It sounds like your confusing the new extern template with `export` (which is all but abandoned). http://www.cppreference.com/wiki/keywords/export
luke
+1  A: 

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.

anon
@Neil: not if the headers are written correctly!
jkp
@jkp .cpp files are not headers
anon
@Neil: my bad. Yes, that is not good practice.
jkp
? He is not talking about #including .cpp files, but about putting all #includes from .cpp into .hpp. Also not-a-good-idea, but so evil as #including .cpp files.
Tadeusz Kopec
+1  A: 

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.

Paul
+5  A: 

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.

jfawcett
+1  A: 

.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.

Tyler McHenry
A: 

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.

Arthur Kalliokoski
`#pragma once` is a de facto standard by now - gcc also supports it, and I believe some others do as well.
Pavel Minaev
+1  A: 

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.

Hans Passant
+1  A: 

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.

Liz Albin