Can someone help clarify how header files work? - c++

I've been working with C++ for a good couple of weeks now, but the mechanism behind header files (or the linker I suppose?) confuses the heck out of me. I've gotten in the habit of creating a "main.h" to group my other header files and keep the main.cpp tidy, but sometimes those header files complain about not being able to find a different header file (even though it's declared in the "main.h"). I'm probably not explaining it very well so here's an abridged version of what I'm trying to do:
//main.cpp
#include "main.h"
int main() {
return 0;
}
-
//main.h
#include "player.h"
#include "health.h"
#include "custvector.h"
-
//player.h
#include "main.h"
class Player {
private:
Vector playerPos;
public:
Health playerHealth;
};
-
//custvector.h
struct Vector {
int X;
int Y;
int Z;
};
-
//health.h
class Health {
private:
int curHealth;
int maxHealth;
public:
int getHealth() const;
void setHealth(int inH);
void modHealth(int inHM);
};
I won't include health.cpp because it's a bit lengthy (but does work), it does have #include "health.h".
Anyways, the compiler (Code::Blocks) complains that "player.h" can't find the types 'Health' or 'Vector'. I thought that if I used #include "main.h" into "player.h" it would be able to find the definitions for Health and Vector sense they're included in "main.h". I figured they would they would sort of tunnel their way though (player.h -> main.h -> health.h). But that didn't work too well. Is there some kind of a diagram or video that could clarify how this should be set up? Google wasn't much help (nor my book).

The best way to think of your header files are as an "automated copy-and-paste".
A good way to think about it (although not how this is actually implemented) is that when you compile a C file or C++ file, the preprocessor runs first. Every time it encounters an #include statement, it will actually paste the content of that file instead of the #include statement. This is done until there are no more includes. The final buffer is passed to the compiler.
This introduces several complexities:
First, if A.H includes B.H and B.H includes A.h, you've got a problem. Because every time you want to paste A, you would need B and it would internally have A ! That's a recursion. For this reason, header files use #ifndef, to ensure that the same part is not read multiple times. This is likely happening in your code.
Second, your C compiler reads the file after all the header files have been "flattened", so you need to consider that when reasoning about what is declared before what.

The other answers here have effectively explained the way header files and the preprocessor work. The biggest problem you have is the circular dependencies, which from experience, I know can be a royal pain. Also, when that starts happening, the compiler starts to behave in very odd ways and throw error messages that aren't super helpful. The method I was taught by a C++ guru in college was to start each file (a header file for instance) with
//very beginning of the file
#ifndef HEADER_FILE_H //use a name that is unique though!!
#define HEADER_FILE_H
...
//code goes here
...
#endif
//very end of the file
This uses preprocessor directives to automatically prevent circular dependencies. Basically, I always use an all uppercase version of the file name. custom-vector.h becomes
#ifndef CUSTOM_VECTOR_H
#define CUSTOM_VECTOR_H
This allows you to include files willie-nillie without creating circular dependencies because if a file is included multiple times, its preprocessor variable is already defined, so the preprocessor skips the file. It also makes it easier later on to work with the code because you don't have to sift through your old header files to make sure you haven't already included something. I'll repeat again though, make sure the variable names you use in your #define statements are unique for you otherwise you could run into problems where something doesn't get included properly ;-).
Good luck!

You have a circular dependency. Player includes main.h, but main.h includes player.h. Resolve this by removing one dependency or the other.\
Player.h should include health.h and custvector.h, and at this point, I don't think main.h needs any includes. Eventually it may need player.h.

includes work very simple, they just command preprocessor to add the contents of the file to where include is set. basic idea is to include headers that you depend on. in player.h you should include custvector.h and Health.h. In main only player.h, because all needed includes will be carried with player. and you don't need to include main.h in player.h at all.
it is good also to make sure that header is included only once. in this question general solution is given How to prevent multiple definitions in C? in case of Visual Studio you can use #pragma once, if Borland c++ there is also a trick but i forgot it.

You want to organize your #includes (and libraries, for that matter) in a DAG (directed, acyclic graph). That's the complicated way of saying "avoid cycles between header files":
If B includes A, A should not include B.
So, using "one big master main.h" is not the right approach, because it's hard to #include only direct dependencies.
Each .cpp file should include its own .h file. That .h file should only include things that it itself requires to compile.
There is usually no main.h, because main.cpp nobody needs the definition of main.
Furthermore, you'll want include guards to protect you against multiple includes.
For example
//player.h
#ifndef PLAYER_H_
#define PLAYER_H_
#include "vector.h" // Because we use Vector
#include "health.h" // Because we use Health
class Player {
private:
Vector playerPos;
public:
Health playerHealth;
};
#endif
-
//vector.h
#ifndef VECTOR_H_
#define VECTOR_H_
struct Vector {
int X;
int Y;
int Z;
};
#endif
-
//health.h
#ifndef HEALTH_H_
#define HEALTH_H_
class Health {
private:
int curHealth;
int maxHealth;
public:
int getHealth() const;
void setHealth(int inH);
void modHealth(int inHM);
};
#endif
The only time you want to aggregate a bunch of #includes into a single header is when you're providing it as a convenience for a very large library.
In your current example, you're going a little overboard - each class doesn't need its own header file. It can all go in main.cpp.
The c preprocessor literally inserts the file from a #include into the file that includes it (unless it has already been inserted, which is why you need the include guards). It allows you to use the classes defined in those files because you now have access to their definition.

Related

C++ headers and cpp files - how the heck do I manage them?

I am getting crazy, cryptic compiler errors when trying to build my solution on VS2010. I'm really having a hard time understanding how these includes work.
Game.cpp
Game.h
Deck.cpp
Deck.h
Card.h
// Game.cpp
#include "Game.h"
All good. Now I need to create a new deck:
// Game.h
private:
static Deck _deck;
Well then I need to include the Deck.h so it knows what it is:
// Game.h
#include "Deck.h"
class Game {
private:
Deck _deck;
}
Okay, thats fine. But now I need to use the _deck in Game.cpp
// Game.cpp
#include "Game.h"
Deck Game::_deck;
void Shuffle(void)
{
_deck = Deck();
_deck.Shuffle();
}
But I get an error saying that "Deck is undefined". But since Game.cpp includes Game.h should Game.h include Deck.h?
If I add Deck.h to Game.cpp I get:
"Uses undefinied class Deck Game.cpp"
and
"Deck class redeclaration Deck.h"
I don't understand this at all...
You should see this stackoverflow question that explains include guards
Why are #ifndef and #define used in C++ header files?
You have a circular include. Luckily for you, a static member doesn't require a full definition when declared, so you can your include in Game.h with a forward declaration:
// Game.h
class Deck;
//....
private:
static Deck _deck;
#include is part of the preprocessor phase that runs prior to your compiler and basically performs a substitution of the text.
The problem you describe has to do with translation units. Basically you can think of a source file (.c, .cpp, .inl, etc.) to be different than a header file (.h, .hpp) in the fact that each source file defines a translation unit that the compiler can operate on. The source file is essentially composed of all the logic in the file plus all of the includes it either directly or indirectly refers to.
The compiler will build object files out of each translation unit and then it is the job of the linker to put them all together into a library or executable binary. Logic inside of other source files is not immediately available to any other source file or header until linking time.
The easiest thing to remember is that header files are defining your interface and source files are defining your implementation. You want your header files to be as light as possible and free from as much of the implementation details as you can to increase compile time speed and loosen coupling between objects. You do this by relying on forward declarations in header files and attempting to keep as few .h references inside of other header files and instead moving those to the source files.
Many modern languages mix the two concepts of interface and implementation and with the power of newer IDEs this isn't much of a problem. I still look back and appreciate the separation in C++, however, as this approach is much more explicit. A client of a well written class should be able to ignore the implementation details and thus the header is all they should need to see to use the class. When you are dealing with libraries in C++ this is often the case as you may only have access to header files.

+ header file, include files in define block or just on the top of the file

What is the best location for a file include in C++? For example:
/*Foo.h*/
#include <string> //Should I place this between the #ifndef #endif?
#include "FooBar.h"
using namespace std;
#ifndef Foo_class
#define Foo_class
class Foo
{
/*XXX*/
}
#endif
/*FooBar.h*/
#ifndef FooBar_class
#define FooBar_class
class FooBar
{
/*XXX*/
}
#endif
/*Foo.cpp*/
#include "Foo.h"
/*XXX*/
/*FooBar.cpp*/
#include "FooBar.h"
/*XXX*/
Should I place the include between the define so that it only gets included when needed? Does it have impact to the system when you don't do that?
Generally, system header files do have protection against erroneous over-including, so this really doesn't matter.
#ifndef Foo_class
#define Foo_class
This pair should always be the first pair of lines of any .h file.
If you are including other .h files or library files which are include guarded, it may not matter, but a good habit nonetheless.
Another good habit, avoid using namespace std; in headers.
Library header files already contain their own #ifdef's so everything is resolved if included in multiple files. So it doesnt matter where you put it.
The best place is at the top.
Only do things different from other people when there is a technical reason to do so.
In this case:
- There is no technical difference between the two, as other answers have pointed out.
- All code I've encountered puts the include guards at the top. Although sometimes they are after the copyright notice, the guards are never after other #includes.
Therefore: put it at the top.
In most cases, it makes no real difference, as long as the inner included file has include guards. Put it where you think makes the most sense!
However, there is a reason for the convention of putting it inside the #ifndef GUARD and that is, when files take a long time load (e.g. they are on a heavily loaded network drive, or on a slow disk), in a large project, the same header file may be included many times in the same project
Let's say we have a "common.h":
#include <iostream>
#include "lesser_common.h"
#include "not_so_common.h"
#ifndef COMMON_H
#define COMMON_H
... stuff goes here ...
#endif
in main.c, we have
#include <iostream>
#incldue "common.h"
#include "myheader1.h"
#include "myheader2.h"
#include "myheader3.h"
Where myheader{1,2,3}.h also include common.h.
Now in theory, the preprocessor will have to read through all of common.h four times, and iostream 5 times. If we move the include guard out, so that when common.h is included, it doesn't include other files, at least we save the three reads of iostream. For a large project, with a huge number of files that include a large number of other files [particularly if you subscribe to the principle of "you shouldn't have to include some other file before using this one"], this can add up to quite a bit of file-reading. It shouldn't be your main choice of how/where you arrange files, but keeping it in mind a little bit is a good idea.
Having said that, most preprocessors are "clever", and understand if the file has include guards at top and bottom the first time around, it doesn't need to read the header the next time.
Also, not including files into your header files unless it's acutally needed is a very good idea - same applies for source files, of course.

About headers, forwards and how to organize a lot of includes

I have 3 classes (it could be 300) , each one with its own header and implementation.
I'd like to write an 'elegant' way to organize the way I load of any class needed by every class of the three. Maybe this example helps...
I have : class1 class2 class3
Every header has:
#ifndef CLASS#_H
#define CLASS#_H
#define FORWARD_STYLE
#include "general.h"
#endif
Every implementation has:
#define DIRECT_STYLE
#include "general.h"
OK
I'm going to write a 'general.h' file in which I'd have :
#ifndef DIRECT_STYLE
#ifndef CLASS1_H
#include "class1.h"
#endif
#ifndef CLASS2_H
#include "class2.h"
#endif
#ifndef CLASS3_H
#include "class3.h"
#endif
#endif
#ifndef FORWARD_STYLE
class Class1;
class Class2;
class Class3;
#endif
// a lot of other elements needed
#include <string.h>
#include <stdio.h"
....
#include <vector.h"
( all the class I need now and in the future )
This is a good structure ? Or I'm doing some idiot thing ?
My goal is having one unique 'general.h' file to write all the elemenst I need...
Are this to work fine ?
Thanks
The basic rules to follow are:
Let each of your source file include all the header files it needs for getting compiled in a standalone manner. Avoid letting the header files include in the source file indirectly through other files.
If you have constructs which will be needed across most source files then put them in a common header and include the header in Only in those source files which need it.
Use Forward declarations wherever you can.There are several restrictions of when you can get away using them,read this to know more about those scenarios.
Overall it is a good idea to avoid including unnecessary code in source files through a common header because it just results in code bloat, so try and keep it to a minimum. Including a header just actually copy pastes the entire header to your source file and Including unnecessary files has several disadvantages, namely:
Increase in compilation time
Pollution of global namespace.
Potential clash of preprocessor names.
Increase in Binary size(in some cases though not always)
This might like a fine idea now, but won't scale and should be avoided. Your general.h file will include a vast amount of files, and thus all files that include it will (a) take ages to compile or not compile at all due to memory restrictions and (b) will have to be re-compiled every time anything changes.
Directly include the headers you need in each file, and define a few forward declaration files, and you should be fine.
The #define in a header will probably be ok, but it can propagate through lots of sources and potentially cause problems. More seriously, any time general.h or any of its includes change your entire project rebuilds. For small projects this isn't an issue, for larger projects it will result in unacceptable build times.
Instead, I utilize a few guidelines:
In headers, forward declare what you can, either explicitly or with #include "blah_fwd.h" as seen in the standard library.
All headers should be able to compile on their own and not rely on the source file including something earlier. This can be easily detected by all source files always including their own header first.
In source files, include what you need (usually you can't get away with forward declarations in source files).
Also note to never use using in headers because it will pollute the global namespace.
If this seems like a lot of work, unfortunately that's because it is. This is a system inherited from C and requires some level of programmer maintenance. If you want to be able to decide at a high level what's used by your project and let the compiler/runtime figure it out, perhaps C++ isn't the right language for your project.

How to include a self-created class in another self-created class's header file?

Say I have created two classes: Tires, and Car.
So I have four files: Tires.cpp, Tires.h, Car.cpp, Car.h.
The Car constructor takes Tires as its parameter. But I am not sure how to modify Car.h to
include Tires.h.
Here's what I've done so far (note: they are in separate files)
Tires.h
#include <iostream>
using namespace std;
class Tires
{
private:
int numTires;
public:
Tires();
};
Tires.cpp
#include <iostream>
#include "Tires.h"
using namespace std;
Tires::Tires()
{
numTires = 4;
}
Car.h
#include <iostream>
#include "Tires.h"
using namespace std;
class Tires; // Tried taking out forward declaration but still didn't work
class Car
{
private:
Tires tires;
public:
Car(Tires); // Edited. Thanks to Noah for pointing out.
};
Car.cpp
#include <iostream>
#include "Car.h"
#include "Tires.h"
using namespace std;
Car::Car(Tires _tires)
{
tires = _tires;
}
Thanks
Your approach seems fine here.
One thing to keep in mind when headers include other headers is that you may find you need to include an include guard:
// At the start of Tires.h:
//
// Only delcare this stuff if this is the first time including Tires.h:
//
#ifndef __myproject_Tires_h__
#define __myproject_Tires_h__
class Tires
{
// [snip]
};
// Close the #ifdef above...
//
#endif
This prevents you from declaring "class Tire {" et al. multiple times, should Tires.h happen to be included twice.
Another is that this line in Car.h is not needed:
class Tires;
This may be useful if you want to have declarations of Tires* or Tires&, but to do what you did next:
class Car
{
private:
Tires tires;
... requires Tires to be a "complete type", for its size to be known, etc. You're already covered by that by having #include "Tires.h" anyway.
Lastly, some consider it bad form to have a using statement inside a header as you have done. This kind of breaks namespaces by bringing in std as a global namespace for all files that use this header. Imagine if every header did this, and did so for multiple namespaces. Eventually this becomes the same as there being no such thing as namespaces, and collisions are more likely.
One thing you need is "include guards" so that you don't get a bunch of compiler errors due to redefinition.
Put something like the following in each of you header files:
#ifndef TIRES_H
#define TIRES_H
// contents of the header file...
#endif
Of course, change the name used for the macro guard (TIRES_H) as appropriate for each file. The macro name needs to be unique - basing it on the header file name is usually good enough. Also, many (most?) compilers support a #pragma once preprocessed directive that prevents headers from being processed more than once, but I still generally use the standard include guards.
This allows headers to be included more than once, since the guards cause subsequent includes of the file to essentially skip the entire contents.
Almost all C/C++ headers should have include guards so users don't need to worry about whether or not a necessary header was already included (the exceptions are headers which need to redefine things differently when included at different times - this is a pretty rare technique). Include guards also enable you to have header files (like cars.h in your example) include the headers they need without regard to what else might also include the headers, so your headers can be self-contained and can be included in any order.
You have already included Tires.h in Car.h. You also have a forward declaration of class Tires in Car.h. You should eliminate either the include or the forward declaration. As you don't handle Tires as reference or pointer and you thus need the "behavior" of class Tires, you should eliminate the forward declaration.
You've basically already answered your own question except that your Car(Tires) constructor has yet to be declared in your Car interface.
But I'd actually not do it that way. Your constructor should be Car(Tires const&) so that you can simply use the forward declaration you've already got in Car.h and not include Tires.h until in Car.cpp. The rest of your code could stay the same, but I'd still make a further change and use initialization rather than assignment in the constructor:
Car::Car(Tires const& _tires) : tires(_tires) {}
Even further, I recommend not EVER using '_' as the first character in any name. There's no need to and too often people get confused about when it is OK and when it is not.
From all files delete line containing "using namespace std;"
From Car.h delete line containing "class Tires;" as it's included from #include "Tires.h"
Now wrap all your header file in header guards.

Purpose of #ifndef FILENAME....#endif in header file

I know it to prevent multiple inclusion of header file. But suppose I ensure that I will include this file in only one .cpp file only once. Are there still scenarios in which I would require this safe-guard?
No, that's the only purpose of the include guards, but using them should be a no-brainer: doing it requires little time and potentially saves a lot.
You can guarantee that your code only includes it once, but can you guarantee that anyone's code will include it once?
Furthermore, imagine this:
// a.h
typedef struct { int x; int y; } type1;
// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;
// main.c
#include "a.h"
#include "b.h"
Oh, no! Our main.c only included each once, but b.h includes a.h, so we got a.h twice, despite our best efforts.
Now imagine this hidden behind three or more layers of #includes and it's a minor internal-use-only header that gets included twice and it's a problem because one of the headers #undefed a macro that it defined but the second header #defined it again and broke some code and it takes a couple hours to figure out why there are conflicting definitions of things.
That's its sole raison d'etre. It's still a good idea even if you think you have that covered; it doesn't slow your code down or anything, and it never hurts to have an extra guard.
The purpose of the guard is to prevent the file from being re included in the same .cpp file more than once. It does not protect against including the file in more than one .cpp file.
If you are sure that a header file isn't included in another header file, then the guard is not required. but it's still good form.
even better form is to use
#pragma once
if your compiler supports it.
Ensuring your code is included only once is the sole purpose of a so-called "header guard".
This can be useful as if there's somewhere a circular dependency between your header files, you don't get caught in an endless loop of including files.
The additional scenario I can think of (and we did it) is to create C++ mocks.
You explicitly in your build define the file GUARD value and then you are able to add your own mock realization via -include my_mock.h as the additional compiler option (we used g++).
my_mock.h
#define THAT_FILE_GUARD
class ThatClass
{
void connect()
{
std::cout << "mock connect" << std::endl;
}
}
Using a header guard like this speeds up the compilation process, imagine having three source files using the header (minus the header guard), that in turn would mean the compiler would have to include the header (parsing and lexing the syntax) multiple times over.
With a header guard, the compiler will say 'Ha! I have seen this one before, and no I will not parse/lex the syntax' thereby speeding up the compilation process.
Hope this helps,
Best regards,
Tom.