I'm trying to freshen up my basic C++ skills after a 2 year break by working on a basic card games program. So I created 3 objects: deck, hand, and card. Everything was working pretty well until I tried to define a global constant deck for the whole program to use and everything got screwed up (the deck is supposed to be all 52 cards in order and is never changed). I'm trying to figure out how to link the following files together:
main.cpp
deck.h
deck.cpp
hand.h
hand.cpp
card.h
card.cpp
Where do I need includes and also where and how do I define my global deck to be used across the program? I made a mess of my existing code to try to include everything in everything and now nothing is compiling correctly. Thanks!
For the deck, just define it in main.cpp. It can be passed by reference to any functions in other classes that would need to manipulate it. As far as headers, #include only the headers you need for the current source file. Including header guards is always a good idea as well, so you don't have to worry about how many times you reference a header.
EDIT
extern was mentioned in another answer. This is necessary if you're actually defining a global object. There are mixed opinions about globals. I've not seen it very often in pure C++.
To answer your question about the global you would declare it as extern in deck.h (I'm assuming that makes sense in your program) and define it in deck.cpp.
For instance:
deck.h
extern Card GLOBAL_DECK[52];
deck.cpp
Card GLOBAL_DECK[52];
Now as for using a global, it is a much better approach to avoid globals, and pass references to an object that lives in a higher scope, or create the object on the heap and pass pointers or references to it (but you have to remember to delete it once you are finished with it).
For the question about where do you need your includes, you should be wrapping each header in include guards like this (replacing HEADER_NAME with the header file name, for instance hand.h becomes HAND_H:
#ifndef HEADER_NAME
#define HEADER_NAME
header contents
#endif //Some people like to put HEADER_NAME here but it isn't really necessary
//unless you are using a lot of precompiler directives, which you shouldn't be
Then include the headers in files that need them. Hand and deck needs card, anything else depends on how you have used them. Since you haven't mentioned which complier/toolset you are using I can't give you specific instructions. But I would compile them by themselves and include what you need to get each file compiling. You may encounter circular dependencies, which means that A requires B to compile which requires A to compile (or a longer chain, but eventually it becomes circular), and you will need to research forward declarations and may need to use references and pointers to solve, or change your design.
Then you need to link the object files together to make an executable. If you are using an integrated IDE like Visual Studio or code::blocks it will do it for you, but you might need to find out what your linker is or set up one if you are using a generic IDE like eclipse.
Global variables (or constants) are declared at the top of a file, below the includes, but above any code.
So for this examples, I would write it simply like this :
#include <iostream>
#include <deck.h>
#include <hand.h>
#include <card.h>
extern deck ... // If we want to use the deck constant anywhere in our program
int main ()
{
...
}
notice that I assumed here that deck is non-constant (which I think would not pose a problem).
But if you absolutely need to use a global constant, you can create a new file, name it deckConstant.cpp for example then write the following in this file :
namespace myGlobalConstant
{
extern const deck ... // put the name of the constant you want
}
and create of course the file deckConstant.h :
#ifndef DECKCONSTANT_H
#define DECKCONSTANT_H
namespace myGlobalConstant
{
extern const deck ...
}
#endif
then in the main.cpp file you just add :
#include <deckConstant.h>
using namespace myGlobalConstant
I hope I understood the question right.
Related
I'm working on a drum pad to learn C++ programming.
I'm using a class called DrumSensor which I need to create 5 times in an array.
I'm using a header file "settings.h" to store variables I'll use throughout my code.
settings.h
extern DrumSensor sensor[5];
settings.cpp
#include "settings.h"
DrumSensor sensor[5];
I've been experiencing a lot with this global object array, but I've never been able to compile it.
I tried to find references such as:
Creating Array of Objects c++
c++ global object
The problem is, no matter how I try to declare my "DrumSensors", I get the following error:
... multiple definition of ...
You can take a look at the code here:
https://github.com/woodencase01/DrumSensor
About the code in your question
The way you have shown it is correct. You declared it in a header (and therefore, by extension, in any source file including that header), and defined it once in a source file.
You must be accidentally linking settings.cpp twice, or accidentally including settings.cpp somewhere, or you accidentally wrote another definition for this array somewhere.
About the code you pointed us to
FWIW, in the GitHub project you linked to, you do not have a settings.cpp, just a settings.h with loads of objects defined in it (i.e. without extern). So the problem may simply be that the code you are building is not the same code that you've been talking about.
Good afternoon all,
I'm writing a program to read license plates that has 11 files currently:
Main.cpp
DetectPlates.h
DetectPlates.cpp
DetectChars.h
DetectChars.cpp
PossiblePlate.h
PossiblePlate.cpp
PossibleChar.h
PossibleChar.cpp
Preprocess.h
Preprocess.cpp
I have a feature allowing showing the intermediate processing steps, or not. Current this is implemented by having a global variable in Main.cpp as follows:
// global variables ///////////////////////////////////////////////////////////////////////////////
const bool blnShowSteps = false;
Then in DetectPlates.h and DetectChars.h, I have the following:
// external global variables //////////////////////////////////////////////////////////////////////
extern const bool blnShowSteps;
So in either DetectPlates.cpp or in DetectChars.cpp I can do something like the following:
if (blnShowSteps) {
cv::imshow("1a", imgGrayscaleScene);
cv::imshow("1b", imgThreshScene);
}
This is done many times in both DetectPlates.cpp and in DetectChars.cpp. So far I have used a global variable as above because I was translating this from a Visual Basic.NET version where the conditional looked at the state of a check box on a form and a global variable was an easy translation to start with.
To make this more "C++ish" I would like to change the global variable to conditional compilation. For example, in Main.cpp I would like to do:
#define SHOW_STEPS // NOTE: comment this line out, or not, to show or not show steps
Then in DetectPlates.cpp or DetectChars.cpp:
#ifdef SHOW_STEPS
cv::imshow("1a", imgGrayscaleScene);
cv::imshow("1b", imgThreshScene);
#endif
The problem is how do I implement this? If I #include "Main.cpp" in DetectPlates.h and/or DetectChars.h I get various errors depending on if I used a multiple include guard in Main.cpp or not, but either way I do not get a compile and also this violates the general practice rule of never including a .cpp file.
One possible answer seems to be adding another .h file, called "MyDefines.h" or similar, with only one line:
// MyDefines.h - single line .h file ??
#define SHOW_STEPS // NOTE: comment this line out to not show steps
But this is not an elegant solution for at least two reasons, for one adding an additional .h file to add one line seems poor, and also that would take the #define SHOW_STEPS out of the beginning of Main.cpp where it would logically be.
Another possible solution would seem to be to add a Main.h file, with the function prototypes and other stuff that is at the top of Main.cpp currently, and then to also add the #define SHOW_STEPS line. This is also not a very elegant solution either since I would be adding an entire .h file to add one line, most C++ programs do not have a Main.h file, and this would still remove #define SHOW_STEPS from being just above function main() where most people would intuitively look when figuring out the flow of the program.
Is there a way to do this where the "#define SHOW_STEPS" line would be in Main.cpp but still be seen in DetectPlates.cpp and DetectPlates.cpp?
As you suspected - place the definition in a header file (.h), and include it wherever necessary.
Either that, or don't use compiler tricks, make a configuration class, and pass the configuration object into the relevant part(s) of the program. Have the configuration class read from a file or be initialised in a relevant way.
Edit: Just to comment on, "To make this more "C++ish" I would like to change the global variable to conditional compilation". Both are pretty dodgy practises. Decent code design is probably what you're looking for!
If you introduce #defines to make your code more "C++ish", you're doing something very wrong.
You don't need to explictly remove the if's at all, the compiler can do this for you, given better circumstances. To start with, change your global variable from extern to static in a header.
...That should be enough. If in doubt, check the asm output.
Make it be defined for your whole project. Like adding -DSHOW_STEPS to GCC command line.
So I'm learning C++ and learning to also use SQLite in my practices for data persistence across application runs, which is lots of fun.
But I bumped into this issue:
The program is a Grade Book, classic Ditel C++ book exercise. I'm structuring my classes as follows:
~/classes/Database.h/cpp // A small wrapper for sqlite3
~/classes/Student.h/cpp // The Student object with name and grades (Uses Database)
~/classes/GradeBook.h/cpp // Takes care of most of the application logic and UI (Uses Database and Student)
~/main.cpp // contains just the main function and base Instances of Database and GradeBook
This is so I can instantiate a Single Database Object from main() and pass it by reference to GradeBook and Student so they can use the Database functions. I tried all possible order of includes and as it turns out only this order has works for me.
Student includes Database.
GradeBook includes Student, gets access to Database.
main.cpp includes GradeBook, gets access to both Database and Student.
The question is, is this right? It seems utterly counter-intuitive that the includes seems to "cascade" backwards from deepest classes to the main.cpp file, in other words, Am I doing this right, or am I missing something?
If so, a little explanation or pointers on how this "cascading" works would be pretty awesome.
Thanks!
First, your header files should use include guards to prevent multiple inclusion:
#ifndef MY_HEADER_H
#define MY_HDEADER_H
// code...
#endif // this file will only ever be copied in once to another file
Secondly, you should explicitly include all of the header files that you need to do what you want to do. Relying on header A to include header B for you is just clunky and, since you're using include guards, you never have to worry about including the same file twice.
So, to answer your question, no, it's not "right" in the sense that it could be "better". main.cpp should include the all of the header files that it needs. All of them. #include is a simple text substitution mechanism. When you #include a file it is literally pasted in. That's it.
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.
Being pretty new to C++, I don't quite understand some instructions I encounter such as:
#ifndef BOT_H_
#define BOT_H_
#include "State.h"
/*
This struct represents your bot in the game of Ants
*/
struct Bot
{
State state;
Bot();
void playGame(); //plays a single game of Ants
void makeMoves(); //makes moves for a single turn
void endTurn(); //indicates to the engine that it has made its moves
};
#endif //BOT_H_
What I don't understand is the "#ifndef BOT_H_" and the "#define -- #endif"
From what I gather, it defines a constant BOT_H_ if it's not already defined when the precompiler looks at it. I don't actually get how the struct inside it is a constant and how it is going to let me access the functions inside it.
I also don't see why we're doing it this way? I used C++ a while back and I wasn't using .h files, so it might be something easy I'm missing.
This is known as an include guard, to prevent the contents of a header file from being #included more than once.
That is, it prevents the contents of the header file from being copied into the file that #includes it when it has already #included it before.
The #define isn't defining a constant for the struct, but it's simply defining a constant with no value. If that constant was previously defined, the struct will not be redeclared.
It's called "include guard". It protects you from redefinitions occuring when a header is included more than once. There's also non-standard #pragma once that does the same thing, but might not be supported everywhere.
It does not define a constant whose value is the struct. It defines a constant with an empty value.
It's there so that the content of the header is not included twice. Basically it says something like:
if (!bot_h_included)
{
bot_h_included = true;
// code from the header
}
this is called a header guard it stops the compiler compiling or including the code more than once it is similar to pragma once
Just a side note, I don't recommend using #pragma once I see it a lot in a MVC compatible compilers but just a couple of weeks ago I was working with HP UX and the HP-CC does not support #pragma once, I strongly recommend using #ifndef/#define combinations.