C++ Compiler Issues - c++

Given the following two header files:
#ifndef EVENT_HANDLER_H
#define EVENT_HANDLER_H
#include <SFML/Window.hpp>
#include <SFML/Window/Event.hpp>
#include "window_handler.h"
class EventHandler
{
public:
EventHandler(WindowHandler & classOwner);
WindowHandler * m_windowHandler;
private:
bool m_leftKeyDown;
bool m_rightKeyDown;
bool m_upKeyDown;
bool m_downKeyDown;
unsigned int m_mouseX;
unsigned int m_mouseY;
};
#endif
AND
#ifndef WINDOW_HANDLER_H
#define WINDOW_HANDLER_H
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include "event_handler.h"
class WindowHandler
{
public:
WindowHandler();
sf::Window m_app;
private:
EventHandler m_eventHandler;
};
#endif
I get the following output:
In file included from window_handler.h:6:0,
from main.cpp:3:
event_handler.h:13:29: error: expected ‘)’ before ‘&’ token
event_handler.h:15:2: error: ‘WindowHandler’ does not name a type
As far as I know, though, I'm doing everything perfectly fine. Am I missing something here?

You have a circular dependency.
When window_handler.h includes event_handler.h you've defined WINDOW_HANDLER_H but haven't actually reached the point where the class is defined. When event_handler.h tries to include window_handler.h it doesn't because of WINDOW_HANDLER_H
As noted, you need to forward declare in event_handler.h by removing the include for window_handler.h and replacing it with:
class WindowHandler;

In event_handler.h, remove the line
#include "window_handler.h"
and replace it with
class WindowHandler;
The issue here is that you have a cycle in your include lists. So because of the include guards, you will either have a file that tries to use an undefined WindowHandler, or an undefined EventHandler. Take a look at the preprocessor output and this should make more sense.

Your headers have a circular dependency of includes. Depending on your needs you might be able to change one to a forward declaration, or you'll have to create a third header with the required common code in it.

Related

C++: almost identical header files, but one gives a peculiar inheritance-related error

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.

Unknown class? C2143 syntax error: missing ";" before '*'

I get the error "C2143: syntax error: missing ';' before '*' in Track.h
I believe this is due to a "missing" class definition.
These are the 3 header files:
Topics.h, the package-level header file, which #includes everything else:
#ifndef Topics_H
#define Topics_H
#include <oxf\oxf.h>
#include "Request.h"
#include "TDPoint.h"
#include "Track.h"
#include "TrackReport.h"
#endif
Then there's TDPoint (as in "3DPoint"), which simply defines a class with 3 long attributes:
#ifndef TDPoint_H
#define TDPoint_H
#include <oxf\oxf.h> // Just IBM Rational Rhapsody's Framework
#include "Topics.h"
class TDPoint {
//// Constructors and destructors ////
public :
TDPoint();
~TDPoint();
//// Additional operations ////
long getX() const;
void setX(long p_x);
long getY() const;
void setY(long p_y);
long getZ() const;
void setZ(long p_z);
//// Attributes ////
protected :
long x;
long y;
long z;};
#endif
But the problem lies here, in the marked line:
#ifndef Track_H
#define Track_H
#include <oxf\oxf.h> // Just IBM Rational Rhapsody's Framework
#include "Topics.h"
#include "TDPoint.h"
class Track {
public :
//// Operations ////
std::string getId() const;
void setId(std::string p_id);
TDPoint* getPosition() const; // <--- This line, the first line to use TDPoint, throws the error
//// Attributes ////
protected :
std::string id;
TDPoint position;
public :
Track();
~Track();
};
#endif
My guess was that the compiler (MS VS2008/ MSVC9) simply didn't know the class "TDPoint." But even defining the class in the same header file as "Track", or using a forward declaration like "class TDPoint" (which then throws the error: undefined class) didn't help.
The code was auto-generated from Rhapsody, if that makes any difference.
But maybe the error is something else entirely?
Topics.h includes TDPoint.h and Track.h
TDPoint.h includes Topics.h
and Track.h includes both Topics.h and TDPoint.h
This feels like a circular include... You should either forward declare your classes to solve it or modify Topics.h to not to have circularity.
You have circular inclusion: The file Track.h includes Topics.h which includes TDPoints.h which includes Topics.h which includes Track.h where the TDPoint class is not declared.
In fact, the TDPoint.h doesn't need any header files at all, it's completely independant (as per the code shown in your question).
The Track.h file only needs to include TDPoint.h, not Topics.h. (And possibly <string>.)
General hint: Include as few headers as possible in a header file.
The other answers are correct, but I would like to add few things for completeness.
1. Cause: your project have circular including, specifically, when you compile "TDPoint.cpp", the compiler will do the following
#include "TDPoint.h" //start compiling TDPoint.h
#include "Topics.h" //start compiling Topics.h
#include "TDPoint.h" //compilation of TDPoint.h skipped because it's guarded
#include "Track.h" //start compiling Track.h
#include "Topics.h" //compilation of Topics.h skipped because it's guarded
//resume compiling Track.h
...
TDPoint* getPosition() const; //=> error TDPoint is not defined
=>C2143: syntax error: missing ';' before '*'
2. Counter measure: replace including in header by forward declaration to remove circle of including, and use including in .cpp files. Specifically, forward declaration means:
(in Topics.h)
#ifndef Topics_H
#define Topics_H
#include <oxf\oxf.h>
#include "Request.h"
class TDPoint; //Forward declaration to replace #include "TDPoint.h"
class Track; //Forward declaration to replace #include "Track.h"
#include "TrackReport.h"
#endif

c++ Base Class Undefined. Including base and subclass in another class

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.

std lib objects as return types and function parameters

I am new to C++ and the idea of header files defining classes is foreign to me. I have the following header file for a Polynomial class that is giving me a lot of errors.
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
class Polynomial {
public:
Polynomial(std::vector <int>&);
Polynomial(const Polynomial& orig);
virtual ~Polynomial();
std::vector <int> getCoeffs();
Polynomial getIntegral(int, int, int);
Polynomial getDerivative(int);
std::string toString();
void integrate(int, int);
void derive();
private:
std::vector<int> coeffs;
};
#endif /* POLYNOMIAL_H */
All of the class methods that include something from the standard lib in their return type definition give me the error: 'vector' (or 'string') in namespace 'std' does not name a type
Also the constructor which takes a vector as a parameter gives the error: expected ')' before '<' token.
I'm sure this is something very obvious, but whatever it is the tutorials I have done haven't gone this deep into classes and class definitions to come across an example like this.
std::vector is defined in the header vector. You need to add the statement
#include <vector>
at the top of your header file. This causes the preprocessor to (effectively) paste the contents of that file in place of the #include statement. Thus the compiler knows what the type std::vector refers to in your class definition.
The same applies to std::string, which is, in turn, defined in the header string. So add #include <string> for that header.
cppreference.com is a good reference to search for types and their respective headers; it is also a good online reference in general for C++.
This is what your header file should look like:
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <string>
#include <vector>
class Polynomial {
...
};
#endif /* POLYNOMIAL_H */

Error while trying to use class in another class

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