Reputation: 107082
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:
#pragma once
declarationclass ClassB;
decleration in ClassA.h and an #include "ClassB.h"
in ClassA.cppThis 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:
Upvotes: 4
Views: 439
Reputation: 76745
These are the guidelines I personally follow :
ClassA
contains a ClassB
so a #include "ClassB.h"
is required. Had the ClassB
type only appear in the file by pointer or reference, a forward reference would have been sufficientClassA.h
first in ClassA.cpp
, and use an arbitrary ordering for the following includes (I'm using alphabetical sort)Regarding other aspects :
#pragma
is non standard, prefer include guardsstd::string
appears in your header file, you have to #include <string>
Upvotes: 9
Reputation: 4871
#pragma once
is non-standard (but widely supported), so you may/may not want to use #ifdef
guards instead.
As for whether you need to #include
any particular header, it depends. If the code only requires a forward declaration, by all means avoid the import by just forward declaring the type.
And with the exception of template stuff, I think it is probably not-too-pretty to place long function definitions in the header files.
Having said that, I think that ClassA.h
should actually include ClassB.h
because any user of ClassA.h
(presumably to use ClassA
) will have to have ClassB.h
. Well, if it is doing anything like allocating it.
Upvotes: 1
Reputation: 23324
Don't use forward declaration of ClassB, when ClassA has a data member of this type. It's OK to use it, when it has a pointers to ClassB, as in:
#pragma once
#include "Father.h"
#include "StructC.h"
class ClassB;
class ClassA : public Father
{
StructC struct_c_obj;
ClassB *class_b_obj;
// Some implementation
};
Upvotes: 1
Reputation: 11797
I usually don't use pragma once
because pragmas are not standad. You could have to port your code to a different compiler where it's not defined, and you'd have to rewrite each with #ifndef ... #define
idiom.
This is because I go straight with #ifndef ... #define
.
Second thing: using many includes in an header file is not a good idea: I always try to minimize them. If you got too much of them, each time you change a little thing in one of them you'll have to recompile each dependent .cpp file.
If that's the case, I adopt the Pimpl idiom, that you can find described here (see the C++ example). Anyway, if the project's size is not that big, I think that your approach is correct.
Upvotes: 0
Reputation: 798486
One thing I've garnered from Python (because it's an absolute requirement there) is "import (include) it in the modules where you use it". This will keep you out of trouble when it comes to having or not having the definitions around.
Upvotes: 0