Your #include habits

Started by
9 comments, last by ToohrVyk 15 years, 4 months ago
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?
Advertisement
That's what I do, but I also strive to avoid using #include in headers. In your example you could forward declare MyStruct in Functions.h and not need to #include "Mystruct.h".
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.
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.
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.
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

[size="3"]Halfway down the trail to Hell...
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.
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 namespacenamespace 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_namespacenamespace 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.
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 .
nice replies!...

Also, in such cases u can add "#pragma once" to instruct the compiler to ignore redundant data amongst the prevailing headers.


Thanks and Regards,
Rohith.H.N
Thanks and Regards,Rohith.H.N

This topic is closed to new replies.

Advertisement