I’m fairly new to C++, but my understanding is that a #include statement will essentially just dump the contents of the #included file into the location of that statement. This means that if I have a number of ‘#include’ and ‘using’ statements in my header file, my implementation file can just #include the header file, and the compiler won’t mind if I don’t repeat the other statements.
What about people though?
My main concern is that if I don’t repeat the ‘#include’, ‘using’, and also ‘typedef’ (now that I think of it) statements, it takes that information away from the file in which it’s used, which could lead to confusion.
I am just working on small projects at the moment where it won’t really cause any issues, but I can imagine that in larger projects with more people working on them it could become a significant issue.
An example follows:
UPDATE: my function prototypes for ‘Unit’ have string, ostream and StringSet among their return types and parameters – I am not including anything in my header file that is used only in the implementation file.
//Unit.h
#include <string>
#include <ostream>
#include "StringSet.h"
using std::string;
using std::ostream;
class Unit {
public:
//public members with string, ostream and StringSet
//in their return values/parameter lists
private:
//private members
//unrelated side-question: should private members
//even be included in the header file?
} ;
//Unit.cpp
#include "Unit.h"
//The following are all redundant from a compiler perspective:
#include <string>
#include <ostream>
#include "StringSet.h"
using std::string;
using std::ostream;
//implementation goes here
A using-directive (
using namespace std;) should not reside in a header unless it is contained within a function. It is bad practice. It is unlikely that every user of your header wants unqualified lookup for everything in a given namespace; the inclusion of unrelated headers can lead to unexpected ambiguity and compilation failures. Personally, I avoid the using-directive inside of functions for the same reasoning, but this is generally considered less harmful.A type alias (either through
typedef std::string string;orusing string = std::string;) should be used carefully. Type definitions have meaning, so you should never redeclare it. For example, this is an error:because of conflicting types.
A using-declaration (
using std::string;orusing std::memcpy;) makes a symbol accessible for unqualified name lookup. It is extremely useful when getting for argument-dependent lookup correct, which usually doesn’t matter unless you’re writing a library. The advice is different depending on if you are bringing in a type or a function. Think of using-declarations with types in the same manner as a type alias: It does not make sense to have multiple definitions under the same name. With functions, all you are really doing is extending overload resolution to include a few more things (although it is usually not necessary).For repeating
#include, you should consider if you actually need to include the file in the header in the first place. Perhaps a forward declaration fits your needs.