I try to reference a struct from another class in my code and it gives me an error, saying I have a syntax problem.
#pragma once
#include "Definitions.h"
#include "GV.h"
#include "UI.h"
#include "Tile.h"
#include "Item.h"
class Figure {
public:
//Figure index
struct FIGURE_TYPE {
//Where to crop the image from
SDL_Rect crop;
int x;
int y;
};
//The game figure
FIGURE_TYPE figure_index[FIGURE_COUNT];
//The figure array
int figure_array[MAP_HEIGHT / 64][MAP_WIDTH / 64];
//Functions
Figure ( void );
bool draw_figures ( SDL_Surface* screen, SDL_Surface* figures, SDL_Rect camera, Figure::FIGURE_TYPE figure_spec[FIGURE_COUNT] );
};
That's the struct in Figure.h,
#pragma once
#include "Definitions.h"
#include "GV.h"
#include "Tile.h"
#include "Item.h"
#include "Figure.h"
class UI {
public:
UI ( void );
void set_camera ( SDL_Rect& camera, Figure::FIGURE_TYPE figure_spec[FIGURE_COUNT] );
bool draw_map ( SDL_Surface* screen, SDL_Rect& camera, SDL_Surface* tiles, SDL_Surface* figures, Figure::FIGURE_TYPE figure_spec[FIGURE_COUNT] );
bool draw_status ( void );
};
And that is where I reference it, from another header file called UI.h. I know there is a problem with referencing structures, I just don't know how to fix it. Simple problem, any one wanna help?
The problem is not that Figure Type is declared outside of Figure.h, or that it is private as opposed to public.
Error Reports
Error 1 error C2653: 'Figure' : is not a class or namespace name c:\users\jim\documents\c++\roguelike\roguelike\ui.h 13 1 roguelike
Error 3 error C2653: 'Figure' : is not a class or namespace name c:\users\jim\documents\c++\roguelike\roguelike\ui.h 14 1 roguelike
Error 2 error C2061: syntax error : identifier 'FIGURE_TYPE' c:\users\jim\documents\c++\roguelike\roguelike\ui.h 13 1 roguelike
Error 4 error C2061: syntax error : identifier 'FIGURE_TYPE' c:\users\jim\documents\c++\roguelike\roguelike\ui.h 14 1 roguelike
You have a circular dependency: UI.h depends on Figure.h, and Figure.h depends on UI.h. You need to break the circular dependency by removing the #include of one file in the other. In this case, since I don't see anything in Figure.h using anything in UI.h, you should just remove the #include "UI.h" from Figure.h and be all set.
Your syntax is fine.
What is not fine is that you have a circular dependency between your headers, and this is breaking your #includes.
In this case, it's leading to Figure not being visible from within "UI.h"; even though your syntax is correct, this causes the errors you've seen because "UI.h" doesn't know that your syntax is correct, because it doesn't know what Figure is.
Do not have circular dependencies. Use forward declarations where possible to help you.
Related
I've been trying to pass my Graphics Manager class to both my Robot and Room class.
But when attempting to pass the class by reference I get 3 errors regarding the pass by reference.
These are the errors I'm referring to:
C2143 syntax error: missing ';' before '*'
C4430 missing type specifier - int assumed. Note: C++ does not support default-int
C2238 unexpected token(s) preceding ';'
I have attempted to change the way I've been passing the classes but with no luck, I have highlighted the areas in which is causing the error as well as the code that i have tried to use to fix the problem.
Any advice in how i could go about fixing these errors is highly appreciated.
I have not included the full .cpp files as they are quite large but I will include a link to a pasteBin with the full script.
GrapicsManager.h
#pragma once
#include <iostream>
#include <SFML/Graphics.hpp>
#include "Room.h"
#include "Robot.h"
class GraphicsManager
{
public:
Room* room; //This does not Flag Up Errors
Robot* robot; //This does not Flag Up Errors
Robot.h
#pragma once
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/System/String.hpp>
#include "GraphicsManager.h"
//#include "Room.h" //This what i had
class Room; //This is what i changed
//class GraphicsManager; //Wasnt sure if i should use it this
//way
class Robot
{
public:
//Graphics Variables
Room* room; //This works after the change
Robot* robot; //This works after the change
GraphicsManager *gm; //This throughs up the error
//This Is what i attemped to use with no effect
//GraphicsManager* gm = new GraphicsManager(room, robot);
Robot.cpp https://pastebin.com/Xd1A3Vii
#include "Robot.h"
Robot::Robot()
{
gm = new GraphicsManager(room, robot); //This tells me gm is
//not declared
this->room = room; //This does not flag up errors
this->robot = robot; //This does not flag up errors
//Room &room = *rm; // attempted to use this but decided not
//to
}
Room.h
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/System/String.hpp>
#include "GraphicsManager.h" //
//#include "Robot.h" //what i orginally had
//class GraphicsManager; //i decided not to do it this way
class Robot; //What i changed it to
class Room
{
public:
//Reference to other classes
Room* room; //This doesnt throw errors
Robot* robot; //This doesnt throw errors
//Refference to graphics manager
GraphicsManager *gm; //This throws the three errors mentioned
};
Room.cpp https://pastebin.com/6R6vnVfy
#include "Room.h"
Room::Room()
{
gm = new GraphicsManager(room, robot);
this->room = room;
this->robot = robot;
It's the classic cicular include issue. GrapicsManager.h includes Room.h and Robot.h which each include GrapicsManager.h again. Now, for example, when compiling GraphicsManager.cpp you include GrapicsManager.h. But before you ever get to the GraphicsManager class definition, you first include Room.h. From there you go straight to include GrapicsManager.h again, but since you have a #pragma once in there, the compiler will simply skip that include. By the time the compiler then gets to the GraphicsManager *gm; member declaration in Room.h, is has never seen a declaration of a type named GraphicsManager. The error message that Visual C++ gives you then
C4430 missing type specifier - int assumed. Note: C++ does not support default-int
is arguably a bit unintuitive. At the point where it encounters the identifier GraphicsManager, an identifier can only mean the start of a declaration. Since GraphicsManager is not a known type, the compiler assumes that identifier must be the name of the entity that is supposed to be declared and you just forgot to specify the type. That's why you get the error message you see. C in the olden days used to allow you to omit the type specifier in a declaration which would just mean to use int as a default. So you would see this error as a result of trying to compile ancient, non-standard C code. That's why the error message contains the explicit note that that's not allowed…
You already added forward declarations for Room in Robot.h and for Robot in Room.h. You'll have to do the same for GraphicsManager…
Im a fairly new programmer so I may not be understanding typedef correctly.
I have 2 classes Enemy.cpp and AI.cpp.
My AI.cpp needs values from Enemy.cpp to be able to process its movements etc. In AI.cpp I hold pointers to values such as position, speed and an enum for the direction the enemy is facing.
The Errors I get are listed below. If there is a more simple way to link an enum variable between classes, im all ears.
below is a working example of the error.
///////MAIN.H/////////////
#ifndef _MAIN_H_
#define _MAIN_H_
#endif // ! _MAIN_H_
///////////////////////////
////////MAIN.CPP///////////
#include "AI.h"
#include "Enemy.h"
int main(int argc, char* args[])
{
Enemy enemy;
}
//////////////////////////////
//////////ENEMY.H///////////////
#ifndef _ENEMY_H_
#define _ENEMY_H_
#include "AI.h"
class Enemy
{
public:
Enemy();
enum Facing
{
LEFT = 0,
RIGHT
};
protected:
AI* EnemiesAI;
//try this as a pointer
Facing EnemyDirection;
};
#endif
//////////////////////////////////
///////////ENEMY.CPP////////////////
#include "Enemy.h"
Enemy::Enemy()
{
EnemiesAI = new AI;
EnemiesAI->LinkEnemyToAI(&EnemyDirection);
}
////////////////////////////////////
/////////////////AI.H//////////////
#ifndef _AI_H_
#define _AI_H_
#include "Enemy.h"
class AI
{
public:
/*this needs to be a pointer, otherwise I have to pass the
value into AI on every update*/
typedef Enemy::Facing *ThisFacing; //Error 3
void LinkEnemyToAI(ThisFacing facing);
private:
//This is a pointer to a Enemy::Facing object
ThisFacing mFacing;
};
#endif
///////////////////////////////////////
////////////////AI.CPP/////////////////
#include "AI.h"
void AI::LinkEnemyToAI(ThisFacing facing)
{
mFacing = facing;
}
////////////////////////////////////////
Error C2653 'Enemy': is not a class or namespace name ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 11
Severity Code Description Project File Line
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 11
Severity Code Description Project File Line
Error C3646 'mFacing': unknown override specifier ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 17
Severity Code Description Project File Line
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 17
Severity Code Description Project File Line
Error C2660 'AI::LinkEnemyToAI': function does not take 1 arguments ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\enemy.cpp 7
Severity Code Description Project File Line
Error C2061 syntax error: identifier 'ThisFacing' ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 13
Severity Code Description Project File Line
Error C2238 unexpected token(s) preceding ';' ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\enemy.h 23
Using include-guards here doesn't help really, because Enemy.h depends on AI.h which depends on Enemy.h and so on forever.
You have to break that chain, and the easiest way to break it is through something called forward declarations.
If you look closer in the Enemy.h header file, all it uses of the AI class is to declare a member variable which is a pointer to AI. That means you don't need the full definition of AI, you only need to tell the compiler that the class AI exists. Something like
#ifndef ENEMY_H
#define ENEMY_H
class AI; // Forward declaration of the AI class
class Enemy
{
public:
Enemy();
enum Facing
{
LEFT = 0,
RIGHT
};
protected:
AI* EnemiesAI;
//try this as a pointer
Facing EnemyDirection;
};
#endif // ENEMY_H
Now in the Enemy.cpp file you still need to #include "AI.h" since the full definition of the class is needed there.
This forward declaration isn't really possible in the AI.h header file, since in it you use the enumeration Enemy::Facing. However, since Enemy.h no longer includes AI.h there's no longer the circular dependency.
Also note that I changed the header guard macro to not have leading underscores, since all symbols with a leading underscore follower by an upper-case letter is reserved in all scopes. See e.g. this question and its answers for more details.
This is my first question, so I apologize in advance for any things about stack overflow that I may not be aware of!
The issue I am having is that I am making a simple SDL program, currently it is just supposed to draw a PNG image (Assets/Board.png) to the screen, but I am being faced with many errors to do with the two classes communicating with each other, I think that I have circular inclusion errors. But I have been trying to fix the problem for days and I haven't been able to solve it.
Here are the errors that I am getting:
http://imgur.com/gallery/vq3XLwU/new
(Here is a text version of it, but the formatting is bad sorry)
1>d:\code\c++\games\chess\chess\manager.h(41): error C2079: 'Manager::Tex' uses undefined class 'Render'
1>d:\code\c++\games\chess\chess\render.h(32): error C2146: syntax error : missing ';' before identifier 'manager'
1>d:\code\c++\games\chess\chess\render.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\code\c++\games\chess\chess\render.h(32): error C2146: syntax error : missing ';' before identifier 'manager'
1>d:\code\c++\games\chess\chess\render.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
(I have used an image because the formatting of the image is easier to read.)
(Also click on the image in imgur to see the zoomed in version)
You can download the entire code project here (ZIP FILE):
https://www.mediafire.com/?og21315fc1d58sk
But here is the code that I think is causing the issues:
(Manager.h file)
//Include guards.
#pragma once
//Headers.
#include "Render.h"
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
//Namespaces.
using namespace std;
//Enumerator.
enum State { Play, Exit };
class Manager
{
public:
Manager(); //Constructor.
~Manager(); //Destructor.
//Rendering.
SDL_Window* Window;
SDL_Surface* Screen;
SDL_Renderer* Renderer;
//Functions.
void Run();
void Init();
void Close();
void Input();
void Update();
void Error(string);
//Game variables.
State state;
Render Tex;
private:
//Constant values.
const int WINDOW_POS_X = SDL_WINDOWPOS_CENTERED;
const int WINDOW_POS_Y = SDL_WINDOWPOS_CENTERED;
const int INIT_FLAGS = SDL_INIT_VIDEO;
const int SCREEN_HEIGHT = 600;
const int SCREEN_WIDTH = 600;
};
(And here is the Render.h file)
//Include guards.
#pragma once
//Headers.
#include "Manager.h"
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
//Namespaces.
using namespace std;
class Render
{
public:
Render(); //Constructor.
~Render(); //Destructor.
//Functions.
void Draw(int, int); //Draws texture at position.
void Load(string); //Loads texture from path.
void Deallocate(); //Destroy texture.
//Getter functions.
int GetHeight() { return Height; };
int GetWidth() { return Width; };
private:
SDL_Texture* Texture; //Actual image.
Manager manager; //Manager class.
int Height; //Height of image.
int Width; //Wdith of image.
};
So in conclusion, I am having errors related to the class objects, which I believe are being caused by circular inclusion, despite my research I have not been able to fix these issues. I would greatly appreciate any help with this issue.
P.S I know I am not supposed to use the std namespace, instead I must write std::foo, I am aware, so please don't comment about it!
In C++ "ownership" is a very important concept. A class "owns" its members. The problem is you have two objects and you've told the compiler that both "own" the other, which won't do. You have to decide which of them owns the other, and has it as a member (or maybe neither owns the other). At least one class must refer to the other, rather than listing it as a child/member. And the best sort of reference is a pointer.
class Manager;
// this forward declaration tell the compiler the class exists, but
// we don't care about the details yet, so we won't include the header.
// if we try to include it, that header refers to Render, which the compiler
// hasn't seen yet, so the compiler will fail.
class Render
{
public:
Render(Manager* parent_); //Constructor.
...stuff...
Manager* parent;
};
Cpp file:
#include "manager.h"
#include "render.h"
Render::Render(Manager* parent_)
: parent(parent_)
{}
SUGGESTIONS:
1. Eliminate the "Render.h" include:
There doesn't seem to be anything in "Manager.h" that needs anything in "Render.h" - so why include it?
Similarly, 2. Eliminate the "Manager.h" include.
You can simply use a "forward declaration", instead of including the whole class interface (.h file).
These links might help:
C++ circular include
Headers and Includes: Why and How
Okay, I think that I have solved the problem, thanks to a variety of comments. The solution may not be ellegant but it works. Instead of defining the Render Tex variabel inside the Manager header, I declared it inside the Manager.cpp class. Once I had done that I can #include "Render.h" inside the Manager .cpp file. I dont know if that explanation is clear but here is the top of the manager.h file:
//Include guards.
#pragma once
//Librarys.
#include <SDL_image.h>
#include <string>
#include <SDL.h>
And here is the top of the Manager.cpp file:
//Header.
#include "Manager.h"
#include "Render.h"
//Librarys.
#include <iostream>
//Objects.
Render Tex;
I wanted to run the game by testing the spawner. I thought that I had properly declared the Spawner class by calling its header file in SceneGame.hpp
When I wanted to use the Spawner* as a vector variable, I thought there would be no compiler errors, but I was wrong.
The source of the error comes from declaring the variable vector spawner_list
Relevant files:
Spawner.hpp
#pragma once
#include <SFML\Graphics.hpp>
#include "weapon.hpp"
#include "movement.hpp"
// forward declare
class EnemyTemplate;
/*
Spawner will create enemies and/or power ups
For spawning enemies, they will recieve one weapon and one movement type
for powerups, only one will spawn and the spawner would disappear afterwards
The spawner will create entities through the following:
Spawn gap: the amount of time to wait between making enemies, in frame ticks
Spawn limit: the amount of enemies to make before being removed
*/
class Spawner{
private:
int spawnGapTime;
int spawnGapSet;
// If you plan to spawn finite enemies, then use constructor
int spawnLimit = -1;
EnemyTemplate* enemyData;
Weapon* givenWeapon;
Movement* givenMovement;
int ticks;
public:
Spawner(Weapon*, Movement*, EnemyTemplate*, std::vector <int>);
void update();
void spawn_enemy();
void spawn_count();
~Spawner(){
delete givenWeapon;
delete givenMovement;
delete enemyData;
};
};
SceneGame.hpp
#pragma once
#include <SFML\Graphics.hpp>
#include "scene.hpp"
#include "game.hpp"
#include "entity.hpp"
#include "movement.hpp"
#include "weapon.hpp"
#include "player.hpp"
#include "collisionGrid.hpp"
#include "spawner.hpp"
// forward declare
class BulletTemplate;
class SceneGame : public Scene{
private:
// skipping some code
std::vector <Spawner*> spawner_list; // The source of the error
public:
SceneGame(Game* game);
// skipping some code
};
Is there any way I can fix this undeclared identifier problem without having to forward declare Spawner?
C2065: 'class' undeclared identifier
If that is the literal text of the error message, you're compiling as C, not as C++.
If it isn't the literal text of the error message, you should have posted the literal text of the error message.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
This class below is causing a horrendous amount of errors. It appears to be fine though. Any C++ Gurus around who know why VC++ hates me?
Entity.h
#pragma once
#include "World.h"
#include "Renderer.h"
class Entity {
public:
Entity(World* world, Coordinate coord);
~Entity();
void render(Renderer renderer) const;
World* world;
Coordinate coord;
};
Entity.cpp
#include "Entity.h"
Entity::Entity(World* world, Coordinate coord) : world(world), coord(coord) {
world->entities.insert(this);
}
Entity::~Entity() {
world->entities.erase(this);
}
The errors themselves don't make a whole lot of sense as they aren't even related to this file. Some of the common errors are unexpected end of file, missing ';' before '{' and "Entity is not a class or namespace name". Those errors do not occur when I do not include Entity in my project. The last of those errors appear in the declaration code of Entity.
The errors (With all duplicates removed): http://pastebin.com/TEMEhVZV
World.h
#pragma once
#include <map>
#include <vector>
#include <unordered_set>
#include "Chunk.h"
#include "Coordinate.h"
#include "Renderer.h"
class World {
public:
~World();
void generateChunk(Coordinate coord);
void loadChunk(Coordinate coord);
void renderWorld(Renderer* renderer);
std::unordered_set<Entity*> entities;
inline Chunk* getChunk(Coordinate coord) const {
return loadedChunks.at(coord);
}
private:
std::map<Coordinate, Chunk*> loadedChunks;
};
Renderer.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include "World.h"
class Renderer {
public:
sf::Window *window;
void bind(sf::Window* newWindow);
void initializeOpenGL();
void renderChunk(Chunk* chunk);
inline void drawPoint(Coordinate coord) {
glBegin(GL_POINTS);
glVertex3d(coord.x, coord.y, coord.z);
glEnd();
}
private:
template <class T>
inline static void pushVector3(std::vector<T>* vertices, T x, T y, T z);
};
To me, it looks like a circular header dependency, meaning something can't be defined.
If your Renderer.h file has a method acting upon an Entity object, and contains this header file as a dependency, Entity will have to be declared before Renderer can be compiled. (The compiler needs to know how big an Entity object will be so it can hard-code the stack offset.)
But similarly, Renderer needs Entity. So it can't be compiled, either!
This may not have shown up in your project before, because the header files are loaded in a different order than now, when the 'Entity' header triggers them.
So, what you should do is modify the headers so there are no circular dependencies, and then reference only pointers in the header, since they have fixed, known sizes. Here are some tricks:
Include low-level classes instead of higher ones.
#include "World.h"
-->
#include "Coordinate.h"
class World;
Use pointers.
#include "Renderer.h"
void render(Renderer renderer) const;
-->
class Renderer;
void render(Renderer* renderer) const;
Doing these, the header files can be moved to your .cpp file:
#include "Entity.h"
#include "World.h"
#include "Renderer.h"
Try going to the very first error its spits out, and fixing that one. In VC++ double-clicking there should take you to the line in question. Often times after the first error or two the compiler is so hopelessly confused that nothing else in its output is worth looking at.
My suspicion would be that it will take you to a line in one of those header files you are not displaying.
It's hard to give too much help without more context. In my experience, errors like this almost always relate to a missing semicolon. Are you given a file and line number with those errors? I would check in Renderer.h, and make sure it is not missing a semicolon.
The reason I suggest this is because, when you #include a file, the compiler actually copies it in to this file. That means that typos in previous files can manifest themselves in these files. If you can post more information, or even copy and paste the errors themselves, I'll try to be more helpful.
EDIT:
Since you've posted your errors, this makes much more sense. If you look, the first error in the list is actually number 148. You have to scroll down for error number 1:
"Error 1 error C2065: 'Entity' : undeclared identifier world.h"
To me, this looks like you're trying to use the class Entity in the file world.h, and it doesn't exist yet. So this looks like a circular include problem.