This is a rather basic question, but it\'s one that\'s bugged me for awhile.
My project has a bunch of .cpp (Implementation) and .hpp (Definition) files.
I f
Some best practices:
Every header is wrapped with:
#ifndef HEADER_XXX_INCLUDED
#define HEADER_XXX_INCLUDED
...
#endif /* HEADER_XXX_INCLUDED */
Headers do not include each others in cycles
These are not necessarily "best practice", but rules which I usually follow also:
#include "..."
and before the system-wide headers, which are included as #include <...>
Check out John Lakos's Large-Scale C++ Software Design. Here's what I follow (written as an example):
// foo.h
// 1) standard include guards. DO NOT prefix with underscores.
#ifndef PROJECT_FOO_H
#define PROJECT_FOO_H
// 2) include all dependencies necessary for compilation
#include <vector>
// 3) prefer forward declaration to #include
class Bar;
class Baz;
#include <iosfwd> // this STL way to forward-declare istream, ostream
class Foo { ... };
#endif
// foo.cxx
// 1) precompiled header, if your build environment supports it
#include "stdafx.h"
// 2) always include your own header file first
#include "foo.h"
// 3) include other project-local dependencies
#include "bar.h"
#include "baz.h"
// 4) include third-party dependencies
#include <mysql.h>
#include <dlfcn.h>
#include <boost/lexical_cast.hpp>
#include <iostream>
// stdafx.h
// 1) make this easy to disable, for testing
#ifdef USE_PCH
// 2) include all third-party dendencies. Do not reference any project-local headers.
#include <mysql.h>
#include <dlfcn.h>
#include <boost/lexical_cast.hpp>
#include <iosfwd>
#include <iostream>
#include <vector>
#endif
Building on what antti.huima said:
Let's say you have classes A, B, and C. A depends on (includes) B, and both A and B depend on C. One day you discover you no longer need to include C in A, because B does it for you, and so you remove that #include
statement.
Now what happens if at some point in the future you update B to no longer use C? All of a sudden A is broken for no good reason.
Organizing code files in C and C++:
There are several problems with the #include model used in C/C++, the main one being that it doesn't express the actual dependency graph. Instead it just concatenates a bunch of definitions in a certain order, often resulting in definitions coming in a different order in each source file.
In general, the include file hierarchy of your software is something you need to know in the same way as you know your datastructures; you have to know which files are included from where. Read your source code, know which files are high up in the hierarchy so you can avoid accidentally adding an include so that it will be included "from everywhere". Think hard when you add a new include: do I really need to include this here? What other files will be drawn in when I do this?
Two conventions (apart from those already mentioned) which can help out:
In A.cpp, always include A.h first, to ensure that A.h has no additional dependencies. Include all local (same module) files before all project files before all system files, again to ensure that nothing depends on pre-included system files. Use forward declarations as much as possible. Use #indef/#define/#endif pattern If a header is included in A.h, you don't need to include it in A.cpp. Any other headers A.cpp needs must be explicitly included, even if they happen to be provided by other .h files.