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.
Related
I have an interface ver as
// ver.h
class ver
{
public:
virtual void func()=0;
};
Then ver1 and ver2 implement this interface. ver1 and ver2 differ in the sense they include header test\header.h and test2\header.h. Now test\header.h and test2\header.h are not under my control and are mostly similar except for a function pointer which is the reason for having ver1 and ver2
// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);
#endif
and
// test2\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_b
);
#endif
Now the implementations
//ver1.h
#include "test\header.h"
class ver1:public ver
{
public:
FuncPoint f;
};
and
//ver2.h
#include "test2\header.h"
class ver2:public ver
{
public:
FuncPoint f;
};
and ver1.cpp and ver2.cpp will be using the respective f
Now the polymorphic behavior comes into play here
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return new ver1();
else
return new ver2();
}
Since something.cpp includes both ver1.h and ver2.h, first test\header1.h gets included and because of the include guards, test\header2.h is not included and hence there is no FuncPoint defined for class ver2 and something.cpp fails to compile.
On the other hand ver1.cpp and ver2.cpp gets compiled successfully since there is only one header.h included.
I could do a #undef header after including ver1.h in something.cpp but that would give redefinition error for other things which are same in test\header.h1 and tes\header2.h.
A simple fix would be to not have FuncPoint f as global variables instead of member variables, this way i won't have to include test\header.h in ver1.h but instead in ver1.cpp.
Is there some other better way to fix this?
EDIT:
I could forward declare struct_type_a and struct_type_b in something.cpp and avoid including ver1.h and ver2.h in something.cpp. But class ver1 and ver2 use other things(to declare members) from test\header.h as well(which are same in both versions).
Don't include header.h in ver1.h or ver2.h but in the respective .cpp files: FuncPoint is a pointer so you can use forward declarations. Since ver1.h and ver2.h will both be included you will need to rename it however where exposed (in the .cpp files you will be able to use the original FuncPoint too, since you include only one definition of it there):
//ver1.h
#include "ver.h"
struct struct_type_a;
typedef void (*FuncPoint_a)(struct_type_a);
class ver1 : public ver
{
public:
FuncPoint_a f;
static ver1 *create();
};
Also the creation of the polymorphic objects must be demanded to methods implemented in the .cpp files, in the create() static method.
Following your code it would become:
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return ver1::create();
else
return ver2::create();
}
In this way the two colliding headers will never be included in the same file.
I've added the inclusion of ver.h in ver1.h (and ver2.h) because this is the source using it. Including it in something.cpp only is not correct (ver1 and ver2 need it) - but not related to the current problem.
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.
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.
Heyo, I have a question about this issue I am having in C++. I am new to C++ and learning. I have experience in object oriented programming so I am looking for the correct way and solve this issue and why it should be done that way.
Classes
I have separated each class into an interface header file and implementation cpp file.
The first class "Alpha" is my base class:
// a.h
#pragma once
class Alpha
{
public:
virtual void myFunction();
};
Alpha Implementation:
// a.cpp
#include <iostream>
#include "a.h"
void Alpha::myFunction()
{
std::cout << "Class Alpha myFunction" << std::endl;
}
I then have a sub class "Beta":
// b.h
#pragma once
#include "a.h"
#include "a.cpp"
class Beta : public Alpha
{
public:
virtual void myFunction();
};
Beta Implementation:
// b.cpp
#include <iostream>
#include "b.h"
void Beta::myFunction()
{
std::cout << "Class Beta myFunction" << std::endl;
}
I then have what will be like a manager class called "Gamma".
// g.h
#pragma once
#include <vector>
#include "a.h"
#include "a.cpp"
class Gamma
{
public:
void run();
std::vector<std::shared_ptr<Alpha>> alphaCollection;
};
Gamma implementation:
// g.cpp
#include "g.h"
#include "b.h"
#include "b.cpp"
void Gamma::run()
{
Beta localBeta;
alphaCollection.push_back(std::make_shared<Beta>(localBeta));
// example usage
alphaCollection.at(0)->myFunction();
}
Then finally my main:
#include "g.h";
#include "g.cpp";
int main()
{
Gamma objectG;
objectG.run();
}
Why I am doing this
The purpose for all of this being that I want a vector of the base class Alpha in my manager where I can then insert elements of a varying number of base class objects.
I used Beta as an example of a derived class but in the real implementation would have more derived classes such as Charlie, Delta etc.
The goal being that my Manager class Gamma will be able to operate on the vector elements as Alpha objects and each of the sub classes perform their own behavior.
The Problem
I cannot compile the above example because of how Gamma's implementation file includes "g.h" and "b.h" each of which include "a.h" and "a.cpp" thus double including "a.cpp" since it has no header guard.
error C2084: function 'void Alpha::myFunction(void)' already has a body a.cpp
error C2264: 'Alpha::myFunction' : error in function definition or declaration; function not called g.cpp
I have read varying opinions on how to use includes and overall I just feel like a noob in understanding the proper way to organize code to prevent his.
Am I very disorganized?
Should implementation files use header guards too?
Should I be using forward declarations? If so how?
Am I crazy to want the implementation to include the sub class includes while the header includes the base class include only?
Seriously any guidance is appreciated!
Do not #include the cpp files. It's not required and that's what is causing the issue.
#pragma once is the same as an include guard - but remember it's not portable - it's specific to your current compiler.
You should not have include guards in your cpp files because you shouldn't #include them.
You only need to include header files, not .cpp files.
You do not want to use header guards in .cpp files.
You don't need forward declaration here (although you could use it instead)
Your implementations are not including "sub class includes", they are including the header files that define their interface. Your include of a.h is correct in g.h.
Stop #including .cpp files. The .h is the most you'll ever need, and sometimes just a forward declaration is enough. Here, here, and here are decent descriptions of what purposes they serve.
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