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

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.

Related

C++ - Class does not name a type

I am instructed to code a Blackjack project for my college CMSC class. I have made all required source files but there is an error that I cannot figure out. I am using the terminal with a Makefile to compile my program.
When I compile my program I get this error in the terminal along with other warnings (I am not concerned about the warnings).
In file included from Blackjack.h:19:0,
from Proj2.cpp:12:
Player.h:17:3: error: ‘Hand’ does not name a type
Hand hand;
^
In file included from Blackjack.h:19:0,
from Blackjack.cpp:1:
Player.h:17:3: error: ‘Hand’ does not name a type
Hand hand;
Here is my source code in a Github repository.
https://github.com/Terrablezach/Blackjack
Can anyone tell me why the class 'Hand' does not name a type? I have included it in my header files where it needs to be included and I don't understand why it does not recognize it as a class.
Thank you in advance for your help.
You haven't included Hand.h in Player.h, so the definition of Hand is not available there.
Looking at the project brief you can change code, correct errors and include orders, however it states you cannot change the function declarations (this will be to limit the possible number of variations in code functionality I would suspect).
The function declaration is simply this line: Player(char *newName, int newFunds)
Looking at your code you are potentially going to run into problems with circular inclusion in your headers.
What you could do is wrap each header in a small piece of logic to prevent the same file from being included multiple times, for example add the lines
#pragma once
// the #pragma effectively does the same as the #ifndef/#define lines,
// its the equivalent of belt and braces if you use both
#ifndef HAND_H
#define HAND_H
//normal hand.h code in here
#endif
that way no matter how many times you call on the hand.h file you cannot end up with a multiply defined/included header. As a matter of rote I do that with all my header files whilst doing rapid development.
In regards specifically to the error Player.h:17:3: error: ‘Hand’ does not name a type
Hand hand; I suspect the previous comment in regards to the include order is correct, however I have no linux environment to hand, but will get back to you later tonight/tomorrow:)
The order of the #include declarations is incorrect.
Player class is dependant upon the declaration of Hand class. So in Blackjack.h the #include for Hand.h must go before the #include for Player.h
#ifndef BLACKJACK_H
#define BLACKJACK_H
#include <vector>
#include "Hand.h" // must be before Player.h include
#include "Player.h"
Alternatively, a forward declaration can be used in Player.h.
class Hand; // forward declaration of class Hand
class Player {
public:
Player();
Player(char *newName, int newFunds);
...
...

Multiple Source .cpp Files Problems

I've separated my large program into a number of .cpp files, e.g. display.cpp, gui.cpp, display.h, gui.h, etc...
These files are separated just for readability, not necessarily indicative of any sort of dependency scheme.
Initially I had a lot of trouble getting them to compile, because functions from display will call functions from gui, AND vice versa. Whichever one I include first, it will still depend on the other's functions. But I finally figured out that I need to first include all the .h files, then include all the .cpp files, in my main program.
Example, in the main_program.cpp:
#include "display.h"
#include "gui.h"
#include "display.cpp"
#include "gui.cpp"
Unfortunately I also realized that in order to compile I had to remove all the other .cpp files from what is considered "source" code in the Visual Studio debugger. That way it just compiles main_program.cpp, including the other files as needed. If I include display.cpp and gui.cpp in the "source" sidebar it will error.
This is probably the wrong way of doing things and I feel like I am doing something wrong. I would like to be able to put all the source files in the sidebar and still have it compile. Of course the above was just an example and I have not two, but more like 10 different .cpp files that all call each others' functions. Please advise on how to better design this.
You generally never want to include .cpp files! Also, you should get used to factoring your code according to dependency hierarchies which shall not include any cycle! For small proframs this is just helpful, for large software it is essential.
The problem is that you've included .cpp files, that's why you had to tell Visual Studio to pretend that these files were not "source" code, because it always compiles source code files. So the simple solution is don't do that.
Including just the header files (.h) in each .cpp file as required should be sufficient. So, for example, if gui.cpp needs to call functions defined in display.cpp, then you should #include the display.h header file at the top of the gui.cpp code file.
Use forward declarations to eliminate any lingering circular dependencies.
That is... not the right way to approach things. If I had to speculate, I'd guess you aren't using function declarations that aren't definitions. A function definition is what you probably have:
void dothing(int param) { //function definition
throw param;
}
What goes in the header is the function declaration, which would be like this:
void dothing(int param); //function declaration
This merely lets other cpp files know that the file exists for calling, but they don't need to know the details. Generally, functions will go in your .cpp files as you (seem to have) done. Each function will have a declaration in a header file:
display.h
#include "velocity.h" //we need the details, so we include
void dothing(int param); //function declaration
class coordinate; // this is a class declaration
//this header needs to know about coordinates
//but doesn't need the details
//otherwise we'd have to include "coordinate.h"
struct object { //class definitions usually go in headers
coordinate* member; //pointers don't need to know the details
velocity speed; //actual object needs the details
float function(float param); //function declaration
};
display.cpp
void dothing(int param) { //function definition
throw param;
}
float object::function(float param) { //member function definition
}
Then, if a cpp file neads access to a function in another cpp file, it includes the appropriate header:
main.cpp
#include "display.h"
int main() {
object a;
a.function(3.4); //can call the member just fine
dothing(4); //it can call the function just fine.
}
Remember that headers should prefer declaring a class (in my example: coordinate to including more headers wherever possible. Also remember that templates have completely different rules altogether.
I had a similar problem before in which I had two header files referencing each other, calling functions, etc. To fix it, I first made sure that all of my header guards were in check (#ifndef HEADER_DEFINE, #pragma once, etc.), then in the class files I would include the header that was being problematic.
e.g. if I have Pie.h and Cherries.h, and Pie.h included Cherries.h and vice versa, then in the Pie.cpp file, I had the include for Cherries.h (and vice versa).

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.

A basic understanding of C++ header files

I have a theory question rather than an error report.
I'm a rookie C++ programmer, trying to promote that away
Using the VC++ VS2008 compiler
I am often finding myself wondering WHY I want to take some actions in header files.
For example look at this code block:
#include "DrawScene.h"
#include "Camera.h"
#include "Player.h"
#include "Grid.h"
#include "InputHandler.h"
#include "GameState.h"
class Controller
{
public:
private:
public:
Controller();
~Controller(){}
void Update();
private:
};
And the hooked up CPP file , controller.cpp along with it
#include "stdafx.h"
#include "glut.h"
#include "Controller.h"
#include <iostream>
Grid* grid_ptr = new Grid();
InputHandler* inputHandler_ptr = new InputHandler();
DrawScene* drawScene_ptr = new DrawScene();
GameState* gameState_ptr = new GameState();
Controller::Controller()
{
}
void Controller::Update()
{
}
What is a good way to decide which includes go where? So far I've been going with the " whatever works" method but I find it somewhat unprofessional.
Now even though you can say my code has X syntax errors and design flaws, please do, but the focal point I would appreciate that information remains on the use of .h VS .cpp files.
Why is there even such a design? And what are the pits and traps to always be treading lightly around when making any kind of OOP based C++ program?
What sparked this question for me btw was that I wanted to notify the reader of the header file there will be objects stored in the controller but assigning these uninitialized objects seemed impossible without making them static.
Note: I stem from C# --> C++ , might help to know. That's kind of my perspective on code at this point.
Thank you in advance for you efforts!
EDIT: 26/08/2010 18:16
So the build time is the essence of good includes. Is there more to be cautious about?
This is my personal opinion rather than a consensus best practice, but what I recommend is: in a header file, only include those headers that are necessary to make the contents of the header file compile without syntax errors. And if you can use forward declarations rather than nested inclusions, do so.
The reason for this is, in C++ (unlike C#, iiuc) there's no export control. Everything you include from a header will be visible to the includers of the header, which could be a whole lot of junk that users of your interface should not see.
Generally speaking headers should reside in the cpp file. For standard library includes (and possibly 3rd library includes) you can stick them in headers. However headers defined specifically for your project should go in cpp files whenever possible.
The reason for this is compilation time and dependency issues. Any time you change a header file, the compiler will have to recompile every source file that includes it. When you include a header file in another header file, then the compiler has to recompile every cpp file that includes either header file.
This is why forward declaration and the PIMPL (Pointer to IMPLementation, or opaque pointer) pattern are popular. It allows you to shift at least some of the changes/implementation out of the header file. For example:
// header file:
class SomeType;
class AnotherType
{
private:
SomeType *m_pimpl;
};
doesn't require you to include "sometype.h" whereas:
// header file
class AnotherType
{
private:
SomeType m_impl;
};
does. EDIT: Actually, you don't need to include "sometype.h" in the "anothertype.h" if you ALWAYS include "sometype.h" before "anothertype.h" in EVERY cpp file that includes "anothertype.h".
Sometimes it can be difficult to move a header file to the cpp file. At that point you have a decision - is it better to go through the effort of abstracting the code so you can do so, or is it better to just add the include?
Only include headers in another header if absolutely necessary. If the header can go solely in the source file then that's the best place. You can use forward declarations of classes in the header if you are only using pointers and references to them. Your DrawScene, GameState, Grid and InputHandler classes looks like they might fall into this category.
Note that C++ as a language does not care about the distinction between headers and source files. That's just an extremely common system used by developers to maintain their code. The obvious advantage of using headers is to avoid code duplication and helps, to an extent, to enforce the one-definition-rule for classes, templates and inline functions.
Avoid putting too many (read, any unnecessary) #includes in your .h file. Doing so can lead to long build times, as e.g. whenever you change Camera.h you will have changed Controller.h, so anything that includes Controller.h will need to be rebuilt. Even if it is only a comment that has changed.
Use forward declarations if you are only storing pointer members, then add the #includes to the cpp file.
Theoretically, .h files contain just the interface, and .cpp files, the implementation. However, since private members are arguably implementation, and not interface, this is not strictly true, hence the need for forward declarations in order to minimise unnecessary rebuilds.
It is possible, in C++, to include the whole implementation inline in the class definition, file, much as you might with Java, but this really breaks the .h/.cpp interface/implementation rule.
Header files contain declarations of functions, classes, and other objects, whereas cpp files are meant for implementing these previously declared objects.
Header files exist primarily for historical reasons. It's easier to build a C++ compiler if the definitions of all functions, classes, etc to be used by your code are given before you actually call them.
Usually you use cpp for your implemenation. Implementing functions in header files automatically inlines them, so unless these are very small and / or very frequently called, this is usually not what you want.

Can someone help clarify how header files work?

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.