Greetings oh mighty coders,
I am a beginner and in a bit of trouble here.
There is my baseclass (sensor.h):
class sensor
{
private:
int sensor_id;
string sensor_name;
string sensor_type;
float reading;
public:
sensor();
sensor(int, char*, char*);
~sensor();
/* Few extra methods here */
};
... and I want to create 4 other classes that inherit from my baseclass sensor
(temperaturesensor, humiditysensor... and so on).
#include "sensor.h"
class temperaturesensor:public sensor
{
public:
Temperatursensor(int, char*,char*);
~Temperatursensor();
/* Few extra methods here */
};
Thing is: Every single one of these classes has to be in its own .cpp/.h file and then be included and used in my main.cpp.
using namespace std;
#include <xyz.h>
/* Other libaries here */
....
#include "temperaturesensor.h"
#include "humiditysensor.h"
int main()
{
sensor* station[2];
station [0] = new temperaturesensor(x,y,z);
station [1] = new humiditysensor(x,y,z);
}
If I include one of them it's no biggie. However: If I use multiple ones I get an redefinition error.
error C2011: 'sensor': 'class' typeredefinition
c:\users\name\desktop\project\sensor.h 14
error c2011: 'temperaturesensor' : 'class' typeredefinition
What can I do to workaround this? Note that I am not allowed to use #pragma once
Sorry for my stupidity and thanks in advance!
You must use:
#ifndef FILE_H
#define FILE_H
.. normal code here
#endif
or
#pragma once
but too, I think, that sensor schould be abstract class and you schould use virtual destructor.
One more think is that array is numerate from 0.
you forgot to use the include guards in your header class,
this is redefining your base class everytime you use it.
so, just do a
#pragma once
or a normal include guard
#ifndef YOURFILENAME_H
#define YOURFILENAME_H
.. normal code here
#endif
Then you will not have the multiple definition error.
The definition of the class sensor is coming from both "temperaturesensor.h"
and "humiditysensor.h". Use guards https://en.wikipedia.org/wiki/Include_guard or #pragma once: https://en.wikipedia.org/wiki/Pragma_once
Related
I can't really describe my problem, so I'll show you here with code what I mean:
boxcollider.h
#include "sprite.h"
class BoxCollider
{
public:
BoxCollider(Sprite sprite);
};
sprite.h
#include "boxcollider.h"
class Sprite
{
public:
BoxCollider coll;
};
INCLUDE issue. How can I solve this problem?
You have two issues. One is the circular references between the two classes. The other is just the circular includes. That one is easy.
All your includes -- ALL of them -- should guard against multiple includes. You can do this two ways.
#ifndef BOXCOLLIDER_H
#define BOXCOLLIDER_H
// All your stuff
#endif // BOXCOLLIDER_H
However, all modern C++ compilers I've used support this method:
#pragma once
As the first line in the file. So just put that line at the top of all your include files. That will resolve the circular includes.
It doesn't fix the circular references. You're going to have to use a forward declaration and pass in a reference, pointer, or smart pointer instead of the raw object.
class Sprite;
class BoxCollider
{
public:
BoxCollider(Sprite & sprite);
};
BoxCollider.h should NOT include Sprint.h, but the .CPP file should.
You can solve this issue by using forward referencing. This would work as follows:
boxcollider.h
#ifndef boxcollider(Any word you like but unique to program)
#define boxcollider(same word as used earlier)
#include "sprite.h"
class BoxCollider
{
public:
BoxCollider(Sprite sprite);
};
#endif
sprite.h
#ifndef sprite(Any word you like but unique to program)
#define sprite(same word as used earlier)
class BoxCollider;
class Sprite
{
public:
BoxCollider& coll; // reference or (smart)pointer
};
#endif
Also don't forget the import guards. These prevent you from importing a file more than once.
For a C++-project, I need to make a game with Doodlebugs and Ants, which are both Organisms. So, I made a class called Organism with the following definition (although I'll probably add way more member functions and member variables, of course).
Organism.h:
#ifndef ORGANISM_H
#define ORGANISM_H
#include "World.h"
class Organism
{
public:
Organism();
~Organism();
virtual void Move() = 0;
friend class World;
int survivalTime;
};
#endif
Organisms live in 'the World', which is a class with (among others) a member variable Organism*** field, a two-dimensional dynamic array containing pointers to Organism objects.
World.h:
#ifndef WORLD_H
#define WORLD_H
#include "Organism.h"
#include "Ant.h"
#include "Doodlebug.h"
class World
{
public:
World();
~World();
void gameplay();
Organism*** field;
};
#endif
You probably already guessed it: Ant and Doodlebug are derived from Organism.
Ant.h:
#ifndef ANT_H
#define ANT_H
#include "Organism.h"
class Ant : public Organism
{
public:
Ant();
~Ant();
void Move();
};
#endif
Doodlebug.h:
#ifndef DOODLEBUG_H
#define DOODLEBUG_H
#include "Organism.h"
class Doodlebug : public Organism
{
public:
Doodlebug();
~Doodlebug();
void Move();
};
#endif
As you can see, Ant.h and Doodlebug.h are almost identical, except for the words Doodlebug and Ant. However, I have two errors.
In World.h, line 16: "'Organism' does not name a type."
In Doodlebug.h, line 7: "expected class-name before '{' token"
Why is this? The first error can be solved by putting class Organism; right before the definition of class World, but I don't understand why that changes anything, since the complete definition of Organism is in Organism.h, which I include.
The second error is the one I'm VERY confused by (and kind of the main reason I'm asking this question), since Ant.h is identical to Doodlebug.h except for the words Ant and Doodlebug, but in Doodlebug.h I get an error but not in Ant.h???
Any help is greatly appreciated.
You have circular dependency between World.h and Organism.h.
World.h has
#include "Organism.h"
and Organism.h has
#include "World.h"
You can remove the above line from Organism.h and replace it with a forward declaration.
class World;
Use forward declaration in header files if you don't need the definition of a as a matter of principle. That will not only avoid problems like the one you encountered but it will also reduce compile time dependecies.
Additional references:
Forward declaration vs include
When can I use a forward declaration?
You did not post your compile command (and most importantly what is the file you try to compile?), but below is what I think your problem is.
The main problem is that your Organism.h includes World.h, which in turn tries to include Organism.h once again, but does not actually include it due to include guards. Therefore, in World.h the compiler still does not know what Organism is and thus generates the first error. You can use forward declaration to solve this: just write
class Organism;
in World.h before class World...; you can also remove #include "Organism.h" from World.h.
I suppose that your second problem can be related to this also.
Note that you can use -E parameter to g++ to generate the file as compiler sees it after preprocessing. Very useful to catch these include-related problems.
The first issue derives from your include "mess". When Organism.h is processed (maybe because a corresponding Organism.cc is compiled) the include statement is replaced by the actual contents, i.e. it is replaced by the contents of World.h. That effectively yields a translation unit where the declaration of World stands before the declaration of Organism, hence leading to the error.
You could also probably remove #include "Organism.h" from your World.h as you have included that in both your Ant and Doodlebug classes, and both of those are included in your World class.
I'm currently writing a simple game with a 2D library and as C++ is a new language to me and as Java is my first fluent programming language, perhaps some bad habits are flowing through to this language that I don't fully understand. I have never had problems doing this in Java but in C++ it causes a ton of errors. As I don't want everything crammed into one class/header file, I've decided to split them up into packages and different classes, but I can't seem to do this without includng the same header files in different places. Here's an example.
Project.h
#ifndef PROJECT_H
#define PROJECT_H
#include "UIManager.h"//this is causing the error, when this, and the class instance is removed the program compiles and runs fine without error
using namespace gamelib;
class Project : public Game {
public:
Project(int argc, char* argv[]);
~Project();
void Update(int elapsed);
void Draw(int elapsed);
void Load();
/*Background*/
Texture * background;
Rectangle* backgroundRectangle;
UIManager ui;
};
#endif
UIManager.cpp
#include "UIManager.h"
void UIManager::load() {
startMenuBackground = new Texture();
startMenuBackground->Load("Sprites/Interface/Transparency.png", false);
startMenuRectangle = new Rectangle(0.0f, 0.0f, Graphics::GetWidth() / 2, Graphics::GetHeight() / 2);
}
UIManager.h
#ifndef UIMANAGER_H
#define UIMANAGER_H
#include "Project.h"
class UIManager {
public:
void load();
private:
Texture * startMenuBackground;
Rectangle * startMenuRectangle;
};
#endif
Now I need all of these includes so I can store the necessary textures, and the Texture and Rectangle come from the API that is being used as a namespace in Project.h
I also need a class instance in Project.h, UIManager ui; So i can use this in the Project.cpp file to call methods
How can I get around this without getting all these errors?
If I understand your problem correctly, you want to avoid including header files multiple times. In that case, what you should do is using Include guards. Which makes sure that the header is included once. Optionally you can use #pragma once at the top of your file but that's another discussion.
Example:
#ifndef UIMANAGER_H // you may choose another name than "UIMANAGER_H"
#define UIMANAGER_H
// Your header file code and includes here.
// Do this for your header files.
#endif
Now, do the same for the other header file but instead naming the macro PROJECT_H or similar.
A good practice is to add in the beginning and in the end of the .h files:
#ifndef FILENAME_H
#define FILENAME_H
//Your code here
#endif
Where FILENAME_H is unique for each .h file.
Those are compiler predirectives, which are not included in the executable, but changes the way that the compiler acts.
Adding those, the compiler won't add the same file twice for the same file. If it's already loaded, it won't load it.
Take in account than in C++, header files are parsed independently on each file of the project.
Typically, the fix would be to change your code to this...
#ifndef UIManager_H
#define UIManager_H
// It's pretty normal to put each class in its own header file.
#include "Texture.h"
#include "Rectangle.h"
class UIManager {
public:
void load();
private:
Texture * startMenuBackground;
Rectangle * startMenuRectangle;
};
#endif // UIManager_H
Since you never instantiate either object though, you don't strictly need a full header.
#ifndef UIManager_H
#define UIManager_H
// Since we only use pointers to the classes, we can forward declare the classes
class Texture;
class Rectangle;
class UIManager {
public:
void load();
private:
Texture * startMenuBackground;
Rectangle * startMenuRectangle;
};
#endif // UIManager_H
You can use the macros #ifndef and #define. This is a common pattern. For example, in your UIManager.h file, have the following:
#ifndef __UI_MANAGER_H__
#define __UI_MANAGER_H__
#include "Project.h"
//Rest of UIManager class definition
#endif
In you Project.h file, have the following:
#ifndef __PROJECT_H__
#define __PROJECT_H__
#include "UIManager.h"
//Rest of Project class definition
#endif
This allows the compiler to compile without errors when it sees circular includes. But it's more preferable to use class forward declaration if possible, but this is a completely different topic.
The macro names __UI_MANAGER_H__ and __PROJECT_H__ are purely randomly chosen. You can choose to use a different naming convention.
Let's say I want to compile something like this:
//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_
#include "Terza.h"
class Prova{
public:
Prova();
};
#endif
and
//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_
#include "EreProva.h"
class Terza{
public:
Terza();
};
#endif
and
//EreProva.h:
//--------------------
#ifndef _EREPROVA_
#define _EREPROVA_
#include "Prova.h"
class EreProva : public Prova{
public:
EreProva();
};
#endif
which doesn't compile saying "'Prova' : base class undefined".
What is the best way to avoid recursion of header between inherited classes?
If you need to have cyclic dependencies there is something wrong with your design and you should revisit your design and try to remove such complex and unwanted cyclic dependencies.
One of overcoming cyclic dependencies is to use Forward Declarations, but note that once you forward declare a type the type becomes Incomplete type for the compiler and there are limitations about what operations you can do with it. You cannot perform any operations on that type instances which need the compiler to know the memory layout of the type.
Good Read:
When can I use a forward declaration?
Sometimes you can work around problems of this sort by tring the following: (1) try adding the "#pragma once" directive at the top of your files, although this may be compiler specific (I used it when developing in VC++ some time ago) (2) instead of including the header files in the class, you can try just add "class Prova", or whatever class it is, to indicate a class which you will define later on but want to "use" now.
Although as Als says, it is better to avoid such designs.
In this code:
//Prova.h:
//--------------------
#ifndef _PROVA_
#define _PROVA_
#include "Terza.h"
class Prova{
public:
Prova();
};
Since you don't use the Tezra class in any way, you don't need the #include. Take it out. Also, you are missing and #endif. Close the #ifndef in this file with a matching #endif in this file.
Moreover:
//Terza.h:
//--------------------
#ifndef _TERZA_
#define _TERZA_
#include "EreProva.h"
class Terza{
public:
Terza();
};
#endif
#endif
You also don't use the EreProva class in this file at all -- so take out the #include statement. You also have an extra #endif at the end of the file. There is only one #ifndef here, so there should only be one #endif. Take the last one out.
I'm writing something in C++. I have 2 classes which I want to contain one into the other as in the folowing (these are just the header files):
//Timing.h
#ifndef _Timing_h
#define _Timing_h
#include "Agent.h"
class Timing{
private:
typedef struct Message{
Agent* _agent; //i get here a compilation problem
double _id;
} Message;
typedef struct MessageArr{
} MessageArr;
public:
Timing();
~Timing();
};
#endif
//Agent.h
#ifndef _Agent_h
#define _Agent_h
#include <string>
#include "Timing.h"
using namespace std;
class Agent{
public:
Agent(string agentName);
void SetNextAgent(Agent* nextAgent);
Agent* GetNextAgent();
void SendMessage(Agent* toAgent, double id);
void RecieveMessage(double val);
~Agent();
private:
string _agentName;
double _pID;
double _mID;
Agent* _nextAgent;
};
#endif
The compilation error is in the Timing.h file inside the definition of the struct:
expected ';' before '*' token
What am I doing wrong?
Try not to include "Agent.h" in Timing.h but include a forward reference instead:
#ifndef _Timing_h
#define _Timing_h
class Agent;
class Timing{
private:
typedef struct Message{
Agent* _agent; //I get here a compilation problem
double _id;
}Message;
typedef struct MessageArr{
}MessageArr;
public:
Timing();
~Timing();
};
#endif
You can include Agent.h in the timing.cpp file.
This way you remove the circular reference and you reduce the coupling between the classes.
Since you don't use the class Timing in your class Agent, you can remove this include as well (but this might be a copy mistake from your shortened example).
Basically - whenever you need either the size of an object or some of it's functionality, you must include its header file. If you don't need it (e.g. if you use only pointers to this object or references), you should not. This reduces compile time (especially for large projects)
For the 1 instance problem - check your favorite design patterns book (e.g. the GoF). The singleton pattern might be what you need.
Rule of thumb.
Do not include other header files from your header files if you don't need to.
Pre-Compiled header file stuff being a notable exception.
If your class only depends on a pointer or a reference you do not need the header file:
Use forward declaration in this situation.
In the source file include only the header files you need to make it work
Include them from most specific to least specific.
This will prevent the problem of hiding a dependency.
Other notes:
Do not use Underscore followed by a capitol letter.
This is reserved for the implementation. see
As in #define _Timing_h
Also note it is traditional that macros are all upper case.
Do not put using namespace X; in a header file
If you do this you pollute the namespace for everybody that uses your header file.
This is a real easy way to PO other developers who now have to re-factor their code to make sure it does not use any of a bunch of new classes/functions/templates that are suddenly being resolved against that was not there before.
So try this:
Timing.h
#ifndef TIMING_H
#define TIMING_H
class Agent;
class Timing{
// STUFF
};
#endif
Agent.h
#ifndef AGENT_H
#define AGENT_H
#include <string>
class Agent{
// STUFF
};
#endif
Timing.cpp
#include "Timing.h"
#include "Agent.h"
// STUFF
Agent.h
#include "Agent.h"
using std::string; // Bring as little as possable into the the global namespace.
// prefer to prefix all cases with std::
// STUFF.
You can't have circular includes.
Stop including "Timing.h" from "Agent.h", since it's not needed there.
Also, you don't need to have the "Agent.h" included in "Timing.h" either, just use a forward reference:
class Agent;
This makes it possible to have pointers to something called Agent.
You need to add the forward declaration of Agent in Timing.h
// Timing.h
#ifndef _Timing_h
#define _Timing_h
class Agent; // fwd declaration.
class Timing{
private:
typedef struct Message{
Agent* _agent; // without fwd decln Agent type is unknown here.
// rest all same.
EDIT:
As suggested by others, you should not be including Agent.h in Timing.h