As a returning newbie to C++, I’m trying to sort the #include methodology.
I’m following a certain set of guidelines I detail below the following example. So far this has worked out for me (the entire project keeps compiling 🙂 ), but I’m worried I may encounter problems in the future, therefore my questions are – is this a correct methodology? Is there a better one? What’s the underlying logic that explains it?
Consider the following example:
Father.h
#pragma once
class Father
{
// Some implementation
};
ClassA.h
#pragma once
#include "Father.h"
#include "StructC.h"
class ClassB;
class ClassA : public Father
{
StructC struct_c_obj;
ClassB class_b_obj;
// Some implementation
};
ClassA.cpp
#include "Father.h"
#include "ClassB.h"
#include "StructC.h"
// Some implementation
ClassB.h and ClassB.cpp
A class without includes
StructC.h
struct StructC {
// Some implementation
};
I follow these guidelines:
- All *.h are headed by a
#pragma oncedeclaration - If ClassA inherits from class Father, it must include it in both *.h and *.cpp file
- If ClassA uses ClassB (and has a ClassB variable declared at the class’s scope), it has a
class ClassB;decleration in ClassA.h and an#include "ClassB.h"in ClassA.cpp - If ClassA uses StructC (and has a StructC variable declared at the class’s scope), it has to include it in both ClassA.h and ClassA.cpp
- If ClassA uses ClassD or StructE but only in the ClassA.cpp file, then it should include them only there
This is probably a clumsy set of guidelines with little understanding of the underlying logic, so I’m probably going to get some wrath… Bring it on, I am trying to learn here… 🙂
UPDATES:
- As some have written below, I have an error in the example – you can use a forward declaration of ClassB in ClassA only if ClassA has a pointer or a reference to ClassB and not if it has a simple ClassB data-member.
These are the guidelines I personally follow :
ClassAcontains aClassBso a#include "ClassB.h"is required. Had theClassBtype only appear in the file by pointer or reference, a forward reference would have been sufficientClassA.hfirst inClassA.cpp, and use an arbitrary ordering for the following includes (I’m using alphabetical sort)Regarding other aspects :
#pragmais non standard, prefer include guardsstd::stringappears in your header file, you have to#include <string>