I have Environment.h file:
#include <windows.h>
#include "interfaces.h"
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
class Environment {};
#endif
and i have Interfaces.h file:
#ifndef INTERFACES_H
#define INTERFACES_H
class IMoving {
public:
virtual void Move() = 0;
};
#endif
in interface IMoving i would like to get an Environment class, to know how to move
class IMoving {
public:
virtual void Move(Environment*) = 0;
};
if i want to do this i need to include environment.h
#include "Environment.h"
and here i'm getting an error, becouse Environment.h - includes Interfaces.h and Interfaces.h - includes Environtment.h. So how to make it work ?
Sorry for spelling mistakes
For circular dependencies one can use Forward declaration(s)
In Interfaces.h just above interface definition, forward declare Environment as follows:
class Environment;
Then when you implement IMoving in a class, you will include Environment.h in its implementation (cpp) file.
You can read more about Forward declaration here.
It looks like you misspelled the class name a few times (Environtment,Envrirontment). Could that be the origin of your issue?
Otherwise I typically use the Forwarded Declaration
Related
I wanted to divide my project into smaller parts cause it started to be unreadable(1000+ lines) and i have some problem with specified .h and .cpp that need to use definitons defined in other files.
Project contains following files:
main.cpp
RPG.h and .cpp
Hero.h and .cpp
Globaldefs.h and .cpp
#ifndef Hero_h
#define Hero_h
#include "Globaldefs.h"
#include "RPG.h"
#include <vector>
using namespace std;
extern class NPC;
extern class Inventory;
class Hero
{
protected:
(...)
Inventory inventory;
(...)
public:
vector<Mob*>::iterator TryAttack(vector <Mob*>& monsters, int & number);
vector<NPC*>::iterator TryTalk(vector <NPC*>& _NPCs, int & number);
};
(...)
#endif
declaration above is from Hero.h file and compilator finds error in line Inventory inventory; (that class is outside, declared in RPG.h and defined in RPG.cpp): 'Hero::inventory' uses undefined class 'Inventory' RPG d:\programming\rpg\rpg\rpg\hero.h 23 I completely don't understand why Mob(other class from RPG.h and .cpp) work properly and NPC defined as extern(too in RPG.h) as well.
#ifndef RPG_h
#define RPG_h
#include "Globaldefs.h"
#include "Hero.h"
#include <vector>
using namespace std;
class Mob;
class NPC;
class Fight;
class Item;
extern class Hero;
(...)
class Meat : public Item
{
(...)
public:
virtual void ActivateEffect(Hero* _hero) { _hero->AddHp(15); };
};
#endif
this is RPG.h file, and there, compilator says that something went wrong in line
virtual void ActivateEffect(Hero* _hero) { _hero->AddHp(15); };
there is: use of undefined type 'Hero' RPG d:\programming\rpg\rpg\rpg\rpg.h 97 and left of '->AddHp' must point to class/struct/union/generic type RPG d:\programming\rpg\rpg\rpg\rpg.h 97
i reserched many sites, but everywhere people has problems with simple adding files to main.cpp, not making internal connections beetween files.
Inclusion guards prevent you to include RPG.h in Hero.h and vice-versa.
What you did is to forward declare Hero in RPG.h, which is good.
But then you did:
virtual void ActivateEffect(Hero* _hero) { _hero->AddHp(15); };
and the compiler needs to know the structure of Hero class to link it to AddHp method. You just cannot do that.
Do that instead (just declare the method):
virtual void ActivateEffect(Hero* _hero);
And remove the #include "Hero.h" line.
Then in the RPG.cpp file do:
#include "Hero.h"
void RPG::ActivateEffect(Hero* _hero) { _hero->AddHp(15); }
We don't see the code for the Inventory problem, but I suppose that's the same problem.
To summarize:
you can include file A.h in file B.h but in that case you cannot include file B.h in A.h
but you can forward declare class B in A.h and reference the pointer/reference on that class, as long as you don't try to use B methods in the header file.
to use B methods in A object, just include B.h in A.cpp and have access to all B method in A.cpp. Some inline methods cannot be implemented in the .h file when they use methods/members of B
You have a circular dependency between RPG.h and Hero.h, and RPG.h line 97, only the forward declaration (extern class Hero;) is visible so you can only reference pointers and references to whole Hero objects and cannot reference members of Hero.
The circular dependency may itself indicate poor design in any case.
Forehand I'd like to mention I'm fairly new to C++ programming and that I'm using Ogre3D as framework (for school project reasons).
I have a class Player which inherits from the GameObject class. When trying to build the project I'm confronted with the following error:
Error C2504 'GameObject' : base class undefined - player.h (9)
Which would imply the GameObject class is undefined within the player class' header file. However I have in fact included the GameObject header file in that of the Player (see code below). I am aware circular including is happening in the code. However if I leave out these includes I get a whole list of different errors on which I'm not sure how or why they occur:
I've been stumped on this problem for a few days now and haven't found any solutions around the Internet as of yet (CPlusPlus article I've mainly been consulting: http://www.cplusplus.com/forum/articles/10627/).
The source files for the below listed header files only include their respective header files.
Player.h
#pragma once
#ifndef __Player_h_
#define __Player_h_
#include "GameObject.h"
class Player : public GameObject {
// ... Player class interface
};
#endif
GameObject.h
#pragma once
#ifndef __GameObject_h_
#define __GameObject_h_
#include "GameManager.h"
// Forward declarations
class GameManager;
class GameObject {
// ... GameObject class interface
};
#endinf
The GameObject header includes the GameManager as can be seen.
GameManager.h
#pragma once
// Include guard
#ifndef __GameManager_h_
#define __GameManager_h_
// Includes from project
#include "Main.h"
#include "Constants.h"
#include "GameObject.h" // mentioned circular includes
#include "Player.h" // "
// Includes from system libraries
#include <vector>
// Forward declarations
class GameObject;
class GameManager {
// ... GameManager interface
};
#endif
To top it of there is the Main class which header file looks like the following:
Main.h
// Include guard
#ifndef __Main_h_
#define __Main_h_
// Includes from Ogre framework
#include "Ogre.h"
using namespace Ogre;
// Includes from projet headers
#include "BaseApplication.h"
#include "GameManager.h"
// forward declarations
class GameManager;
class Main : public BaseApplication
{
// ... Main interface
};
#endif
With all the reading I did on the subject and other individuals with the same error I'd figure I would be able to figure it out but yet to no avail. I hope someone can take the time to help me out here and point out any faulty code or conventions.
I think the easiest way to fix the problem is to change your model for including header files. File A.h should only include B.h if B.h defines a symbol that is used (directly) in A.h. It's also generally a bad idea to put a using clause in a header file - let the programmer of the client code make that determination. Drop forward declarations for classes unless they are absolutely necessary; there's no need for the class GameManager right after #include "GameManager.h". I suspect something else is wrong with the code, but the forward declarations for the classes are hiding that problem. If changing the includes does not fix the problem, start with a single .cpp file that includes the "simplest" header (the one that doesn't depend on any others) and build up to the full set of includes.
I'm new to C++ abstract classes and I'm trying to learn how to work with it. So I started by defining an abstract class with only pure functions, let's call this class SceneObj, so far so good. Afterwards, I start by defining a new abstract class that I'm calling IScreen; this new Class is, also, another abstract class, but it add new requirements.
Unfortunately when trying to compile this simple code I ran into the following error: error C2011: 'IScreen' : 'class' type redefinition.
I'm using Visual Studio 2012 and the code that I'm trying to compile is the following:
#include <stdlib.h>
using namespace std;
class SceneObj
{
protected:
float center;
public:
virtual void SetCenter(float,float,float) = 0;
virtual void SetCenter(float) = 0;
virtual float GetCenter() = 0;
virtual ~SceneObj();
};
class IScreen : public SceneObj
{
public:
virtual void SetCenter(float,float,float) = 0;
virtual void SetCenter(float) = 0;
virtual float GetCenter() = 0;
virtual float GetStartCorner() = 0;
virtual void SetSize(float,float) = 0;
virtual void SetSize(long) = 0;
virtual long GetSize() = 0;
virtual ~IScreen();
};
Could someone point me what/where is the flaw in this code?
edit: Changed code to a minimal one
edit2: This is in a header file and apparently if i change it to a .cpp it compiles without problems. But I needed/wanted to declare my class in headers and then define then in .cpp.
C++programs also use the preprocessor to define header guards. Header guards
rely on preprocessor variables. Preprocessor variables have one of two
possible states: defined or not defined. The #define directive takes a name and defines
that name as a preprocessor variable. There are two other directives that test whether
a given preprocessor variable has or has not been defined: #ifdef is true if the variable
has been defined, and #ifndef is true if the variable has not been defined. If the test is
true, then everything following the #ifdef or #ifndefis processed up to the
matching #endif.
We can use these facilities to guard against multiple inclusion as follows:
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data {
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif //SALES_DATA_H
For instance, in the header file you will find something LIKE the follwing:
#ifndef __*__SceneObj
#define __*__SceneObj__
//Place the abstract class here
#endif
So you have to put the abstract class in between the #define and the #endif. (This is the definition the compiler will consider). you simply don't have these etiquettes on the cpp file. That is why it works there.
Additionally try to have one class per header file, so do not declare the child class on the same header file.
It means that somewhere you already have defined type IScreen. Usually the compiler gives a reference to the duplicated definition.
So investigate the error message.
As for you code snippet then it is irrelevant.
MS VS usually gives several messages if it found an error.
Another reason can be that you included the cpp module with member function definitions in the module with main.
For example
Header file: header.h
#include <stdlib.h>
using namespace std;
class SceneObj
{
//...
};
class IScreen : public SceneObj
{
//...
};
cpp module with member function definitions: module,cpp
#include "header.h"
//...
module with main
#include "header.h"
#include "module.cpp"
//...
Also include directive
#pragma once
in your header file.
I have a class GameObject which has a vector of Component and Transform.
The Transform is a Component but can be accessed on it's own.
I'm getting a Base class undefined error on Component when I try to include both Component.h and Transform.h in GameObject.
Error Message:
Error 1 error C2504: 'Component' : base class undefined c:\users\pyro\documents\visual studio 2010\projects\engine\main\transform.h 9
GameObject.h
#ifndef _GameObject
#define _GameObject
#include "Core.h"
#include "Component.h"
#include "Transform.h"
class Transform;
class Component;
class GameObject
{
protected:
Transform* transform;
vector<Component*> components;
};
#endif
Component.h
#ifndef _Component
#define _Component
#include "Core.h"
#include "GameObject.h"
class GameObject;
class Component
{
protected:
GameObject* container;
};
#endif
Transform.h
#ifndef _Transform
#define _Transform
#include "Core.h"
#include "Component.h"
//Base class undefined happens here
class Transform : public Component
{
};
#endif
I've found a bunch of other topics, but they don't really address the problem I'm having.
So the question is this: why am I getting this error and how do I fix it?
There are a couple of problems with your code:
1. Circular dependency
GameObject.h includes Component.h, and Component.h includes GameObject.h.
This circular dependency breaks everything. Depending on which file you're "starting from", either GameObject will not be visible from Component or vice versa, due to the inclusion guards.
Remove the circular dependency: you don't really need those #includes at all, as you're already using forward declarations. In general, minimise the use of #include in headers.
2. Syntax error
When you've fixed that, add in the missing }; in Component.h.
(Your definition for Transform thinks it's a nested class inside Component which, at that point, has not been fully defined.)
3. Reserved names
This may not cause you a practical problem today, but your macro names should not begin with _ as these are reserved for implementation (compiler) use.
Suppose some source file has a #include "Component.h" directive and no other #include directives. Here's what happens, in order:
The preprocessor symbol _Component is defined.
The #include "GameObject.h" directive in Component.h is expanded.
The #include "Component.h" directive in GameObject.h is expanded.
This does nothing because _Component is now defined.
The #include "Transform.h" directive in GameObject.h is expanded.
The definition of class Transform in Transform.h won't compile because the base class Component has not been defined yet.
The problem is that you have too many superfluous #include statements. For example, there's no need for GameObject.h to include Component.h. The forward declaration is all that is needed. In general, don't include a file in a header unless you truly do need it. If you do need to do so, you need to be very careful of circular inclusions.
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