7

I'm new to programming and the topic of header files is sort of bogging me down after I started using a lot of them. In addition to that I'm trying to use precompiled headers. I'm also using the SFML library so I have those headers that also have to be included.

Right now I have stdafx.h, main.cpp, then classes A, B, C, and D contained within A.h, A.cpp, B.h, B.cpp, C.h, C.cpp, D.h, and D.cpp.

What order would I go about including the headers in all files if

  • all classes contain an instance of an SFML class
  • class D contains an instance of class A and class C
  • class C contains an instance of class B My code: (note: all headers have header guards)

stdafx.h:

#include <SFML/Graphics.hpp>
#include <iostream>

A.h

#include "stdafx.h"
class A
{
    //sfml class
};

A.cpp

#include "stdafx.h"
#include "A.h"

B.h

#include "stdafx.h"
class B
{
    //sfml class
};

B.cpp

#include "stdafx.h"
#include "B.h"

C.h

#include "B.h"
class C: public B
{

};

C.cpp

#include "stdafx.h"
#include "C.h"

D.h

#include "A.h"
#include "C.h"
class D
{
    A a;
    C C; // if left uncommented I recieve a '1 unresolved externals' error
    //sfml class
}

D.cpp

#include "stdafx.h"
#include "D.h"

main.cpp

#include "stdafx.h"
#include "D.h"
orod
  • 81
  • 1
  • 5
  • Does the `main.cpp` uses any of the classes `A,B,C,D` ? – Mahesh Apr 05 '11 at 22:48
  • Sometimes it is helpful to think of it this way: When the preprocessor goes through your files, it will put all the included headers and the cpp source file in one big file, and then compile it. So imagine your program in one big file, and then think about what makes sense for the order. – WildCrustacean Apr 05 '11 at 22:48
  • I normally include them in alphabetic order by category from high level to low level: core (i.e. standard), platform (e.g. Qt, Windows), 3rd party libraries, then my program. With include guards the order doesn't matter, but doing it that way makes it easier to see what is there and if I need to add something when I use a class. I also always include everything used in the file, even if I know it is included in a header somewhere: headers can change, even if infrequently, and it makes my intent clearer. –  Apr 05 '11 at 22:58

5 Answers5

10

My philosophy is that in well-written code, header files should include all other header files that they depend on. My reasoning is that it should not be possible to include a header file and get a compiler error for doing so. Therefore, each header file should (after the #ifdef or #pragma once include guard) include all other headers it depends on.

In order to informally test that you've remembered to include the right headers in your header files, *.cpp files should #include the minimum set of header files that should work. Therefore, if there are separate header files for A, B, C and D, and your cpp file uses class D, then it should only include D.h. No compiler errors should result, because D.h #includes A.h and C.h, C.h includes B.h, and A.h and B.h include the SFML header (whatever that is). C.h and D.h can include the SFML header if it seems appropriate, but it's not really necessary, if you can be sure that the dependencies (B.h and A.h) already included it.

The way Visual C++ does "precompiled headers" screws up this logic, however. It requires you to include "StdAfx.h" as the very first header file, which causes many developers to simply put all #includes for the entire project in StdAfx.h, and not to use #include in any of the other header files. I don't recommend this. Or, they will put all external dependencies in StdAfx.h (e.g. windows.h, boost headers) and #include the local dependencies elsewhere so that changing a single header file does not necessarily cause the entire project to rebuild.

The way I write my code, most of my CPP files include StdAfx.h, and the corresponding .H file. So A.cpp includes StdAfx.h and A.h, B.cpp includes StdAfx.h and B.h, and so forth. The only other #includes placed in a cpp file are "internal" dependencies that are not exposed by the header file. For example, if class A calls printf(), then A.cpp (not A.h) would #include <stdio.h>, because A.h does not depend on stdio.h.

If you follow these rules then the order that you #include headers does not matter (unless you use precompiled headers: then the precompiled header comes first in each cpp file, but does not need to be included from header files).

Qwertie
  • 16,354
  • 20
  • 105
  • 148
  • I believe I am following your answer correctly however when D.h contains an instance of class C I receive the following error: fatal error LNK1120: 1 unresolved externals When the instance is commented out it compiles just fine. – orod Apr 06 '11 at 00:23
  • What external does it claim is unresolved? Your example contains no methods or global variables. Classes themselves are not processed by the linker (the linker deals mostly with functions and static/global variables), so the linker has nothing to complain about in the code you posted above. – Qwertie Apr 11 '11 at 19:09
1

Take a look at a similar question to learn a good approach to authoring headers.

In short, you want to define each header inside a definition guard that prevents headers from being included more then once during compilation. With those in place, for each .h and .cpp file, just include the headers needed to resolve any declarations. The pre-processor and compiler will take care of the rest.

Community
  • 1
  • 1
Brent Worden
  • 10,624
  • 7
  • 52
  • 57
  • stdafx.h includes the SFML headers, A.h, B.h, C.h, and D.h. All of my headers have header guards and only include stdafx.h. All of my source files also only include stdafx.h. Now whenever I compile I get a ton of 'Missing Type' errors, I assume because each header is only being included once when compiled so the next class that uses that header doesn't include it. This is why I was asking what order do I include the headers in. I'm using Microsoft Visual C++ 2010 Express Edition. – orod Apr 05 '11 at 23:05
1

A.h should include SFML

A.cpp should include A.h

D.h should include SFML, A.h and C.h

D.cpp should include D.h

main.cpp should include whichever of A, B, C, D and SFML that it uses directly.

Generally in a .cpp file I don't include any headers that you know must be included by its corresponding .h because they contain the definitions of data members of classes defined in that .h. Hence, in my code D.cpp would not include A.h. That's just me, though, you might prefer to include it anyway just to remind you that the .cpp file (presumably) uses it.

This leaves stdafx - where you need this depends what uses the things in it. Probably it's needed everywhere, and MSVC doesn't process (or processes but discards?) anything before #include "stdafx.h" in a source file, so it should be the first thing in each .cpp file and appear nowhere else.

All header files should have multiple-include guards.

You could add SFML (or anything else you feel like) to stdafx.h, in which case you might as well remove those includes from everywhere else.

Once you've done this, it no longer matters what order you include the headers in each file. So you can do what you like, but I recommend Google's C++ style guide on the subject (click on the arrow thing), adjusted to account for stdafx.h.

Laurie Stearn
  • 959
  • 1
  • 13
  • 34
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
1

C inherits class B. So, it should see the identifier B. So, include B.h here -

#include "B.h"    // Newly added
// Or you can forward declare class B ; 
class C: public B
{

};

D has objects of class A, B. So, include headers of A, B in the "D.h" itself.

class D
{
    A a;  // Should see the definition of class A
    C c;  // Should see the definition of class B
    //sfml class
}

D.cpp

#include "A.h"
#include "C.h"
#include "D.h"  // Notice that A.h and C.h should definitely placed before

Note that every header needs to be included in it's corresponding source file. Think of each source file independently and see whether what ever is used is earlier defined or not in the source file.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • For some reason D.h won't see the definition of class C. – orod Apr 06 '11 at 01:22
  • Strangely D will compile if contains a pointer to class C, but I get an unresolved external error if its not a pointer. Oh well, I'll just work around this. – orod Apr 06 '11 at 01:47
0

Depends on dependencies. Unlike C# and other similar languages, C++ does things in the order it is written, so there may be an issue. If you do have a problem with the order then it will not compile.

bguiz
  • 27,371
  • 47
  • 154
  • 243