Sign in to follow this  
Wavarian

Your #include habits

Recommended Posts

Let's say you had a data structure defined in its own header file: MyStruct.h
struct MyStruct
{
	//...
};

And you had a function which took the data structure in as a parameter declared in another header file: Functions.h
void Function(const MyStruct&);

If you then wanted to call Function() from main() for instance, would you include BOTH "MyStruct.h" and "Functions.h", or just "Functions.h"? Main.cpp
#include "Functions.h"
#include "MyStruct.h"

int main()
{
	MyStruct temp = {...};

	Function(temp);

	return 0;
}

I've made it a habit to include both, even though I know "Functions.h" includes "MyStruct.h". Is this a good habit to have?

Share this post


Link to post
Share on other sites
I always include the headers that are needed for that particular file. In your example, I would include both files because one defines the class and the other declares the function, and I need both the class and the function.

If I only included the function header, and that file is changed to not include the class header (after all, only a forward declaration of the class is need in that case), the code for main breaks also.

Share this post


Link to post
Share on other sites
I'd just forward declare MyStruct in Functions.h instead of including the header. If the full class was needed, then I'd include MyStruct.h in Functions.h. I believe that you shouldn't need to worry about the include order of files, including one header should include or forward declare everything it needs.

Share this post


Link to post
Share on other sites
Fair enough. I don't use forward declarations unless I encounter a circular dependency (which is rare).

I agree with Bob's idea that you should include both just in case something changes. Guess I just needed to be reassured that I wasn't wasting my time putting in so many #includes.

Share this post


Link to post
Share on other sites
I would include both since "functions.h" shouldn't pull in headers that it doesn't absolutely need for it's own definition. It creates an artificial code dependency. In this case, you should use a forward declaration in function.h of MyStruct and then have both includes in main, where you actually create instances of each object.

In this particular case, it won't make much of a difference, but as your project gets larger, it can impact your compile time. It is also good practice to not make your libraries have a bunch of interdependence. There's a much better explanation in the book "Large Scale C++ Software Design".

cheers,

Bob

Share this post


Link to post
Share on other sites
I #include as little as possible, preferring forward declarations when they are sufficient and only #including when I have to. I don't mind the scenarios where this can cause a build failure on a change -- in fact, I want the compile to fail in such a case, because it means I didn't consider a dependency path.

Such changes happen less often than the total number of builds, and preferring less includes (and sometimes using PCHs) help increase build speed.

Share this post


Link to post
Share on other sites
In my current project, which is starting to get large'ish, I have enforced a pretty strict #include policy:

Each namespace has a Forward.h file which contains forward declarations for all classes in that namespace and a typedef for it's smart pointer:

#include <parent/Forward.h> // Let me access anything I need in the parent namespace

namespace parent { namespace child {
class ClassName;
typedef boost::shared_ptr< ClassName > class_name_ptr;
} }



Each header in the namespace then only includes Forward.h files. The trick is to use the typedef'ed pointer whenever I need a class:

#include "Forward.h"

#include <other_namespace/Forward.h> // I need something from other_namespace

namespace parent { namespace child {

class ClassName {
public:
ClassName();
~ClassName();

// [...]
private:
other_namespace::class_in_other_namespace_ptr mCION;
};

} }



Then in the source file I include whatever is needed to make the classes complete.

This works really well, and it solves just about all dependency problems. The only cases where a non-Forward.h header needs to be included in a header is if
a) The class inherits from another class.
b) A needed class is templated.
c) It contains small POD structs, typedef's or enums.

All cases can be solved with just a little care.

Share this post


Link to post
Share on other sites
If you use MyStruct independently of your use of Function, then you should include both headers. If you only use MyStruct for Function, or don't use it directly at all, then just include "Function.h". I try to go for the "include is documentation" thing.

If MyStruct is the kind of thing you don't need to use yourself to use Function, then it shouldn't be included.

My $0.02 .

Share this post


Link to post
Share on other sites
Quote:
Original post by Rohithzhere
Also, in such cases u can add "#pragma once" to instruct the compiler to ignore redundant data amongst the prevailing headers.
No. '#pragma once' (besides being non-standard) merely avoids multiple inclusion of a given file within the same translation unit.

If you include MyStruct.h in Functions.h, then changing MyStruct.h will cause every file that includes Functions.h to be compiled again, even when it doesn't use MyStruct.h or anything defined inside it, and #pragma once will not be able to do anything about it.

Changing a file and having a 30-minute recompile is pretty annoying in large projects.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this