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;
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…
I know this been asked a number of times but no answers seem to solve this.
I have two files.
Main.cpp
#include <irrlicht\irrlicht.h>
#include <vector>
#include <string>
#include <iostream>
#include "Scene.h"
#include "Camera.h"
#include "Gui.h"
irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver;
int main() {
device = irr::createDevice(irr::video::EDT_SOFTWARE, irr::core::dimension2d<irr::u32>(640, 480), 16, false, false, false, 0);
if (!device)
return 1;
device->setWindowCaption(L"NeoTrap");
driver = device->getVideoDriver();
sceneManager = device->getSceneManager();
GUIEnvironment = device->getGUIEnvironment();
//Testing
Mesh* ground = new Mesh();
//Testing
while (device->run()) {
driver->beginScene(true, true, irr::video::SColor(255, 120, 102, 136));
sceneManager->drawAll();
GUIEnvironment->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Scene.h
#ifndef _SCENE_HEADER_
#define _SCENE_HEADER_
irr::scene::ISceneManager* sceneManager;
struct Mesh {
public:
Mesh();
private:
};
class Scene {
public:
Scene();
private:
};
#endif
What I am trying to do is declared a variable in Scene.h and define it from within the main function. I am not sure if I don't understand include guards, but I am getting weird errors:
'irr': is not a class or namespace name
syntax error: missing ';' before '*'
missing type specifier - int assumed. Note: C++ does not support default-int
but when I move the following line back in the Main.cpp file
irr::scene::ISceneManager* sceneManager;
the program compile. When am I not able to declare it in scene.h and set the value from the main function?
It's best to not declare variables in headers. It ends badly far more often than not because every file that includes the header will make their very own sceneManager. When the linker comes along to put the program together it may find dozens of sceneManagers all with an equal claim to being the real sceneManager, throw its hands up in disgust, and spray error messages all over the console.
In scene.h add
#include <irrlicht\irrlicht.h>
up at the top to declare all the bits and bobs of irrlicht so that they are available in scene.h.
Then change
irr::scene::ISceneManager* sceneManager;
to
extern irr::scene::ISceneManager* sceneManager;
extern tells the compiler that sceneManager exists and storage will be allocated somewhere else. The compiler smiles and carries on, leaving sorting out where the one, true sceneManager is to the linker.
Finally, put
irr::scene::ISceneManager* sceneManager;
in Main.cpp to allocate storage so that the linker has a sceneManager to find.
Documentation on extern
Recomended reading: When to use extern in C++
You are declaring that sceneManager is of type irr::scene::ISceneManager*, but the irr namespace doesn't exist when you are declaring that variable. Add an include to the header file that declares that namespace before declaring your variable.
After that, you'll need to declare sceneManager to be extern in the header so that each compilation unit that includes that header doesn't create its own instance of the variable. Then because it is extern, you will also want to redeclare it (without extern) in main.cpp.
Current program layout. The left operand includes the right one.
source.cpp
app.hpp // Also includes SFML libraries with sf namespace
game.hpp
ball.hpp
brick.hpp
plate.hpp
The implementation of ball class (ball.cpp) throws a lot of errors "sf does not name a type".
source.cpp
#include "app.hpp"
int main () {
App app(640, 480, "Arkanoid");
while (app.getWindow()->isOpen()) app.run();
return 0; }
app.hpp
#ifndef ArkanoidApp
#define ArkanoidApp
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "game.hpp"
// code
#endif
game.hpp
#ifndef ArkanoidGame
#define ArkanoidGame
#include "ball.hpp"
#include "brick.hpp"
#include "paddle.hpp"
// code
#endif
ball.hpp
#ifndef ArkanoidBall
#define ArkanoidBall
class Ball
{
public:
Ball(void);
void draw(void);
public: // Setters & getters
private: // Variables
sf::CircleShape circle; // sf is not a class type
sf::Vector2i position; // sf is not a class type
sf::Vector2f direction; // sf is not a class type
private: // Constants
int RADIUS = 8;
int VELOCITY = 6;
};
#endif
Well if your app.hpp includes the sf, of course ball.cpp wouldn't know about it and throw an error, you would need to include the sf inside the ball.cpp as well.
To avoid multiple definitions use #pragma once in your header files.
Other then that it's unclear what and why are you trying to do, if you get to a point where files should include each other it's not a very good design and should be avoided, best design is a tree one.
edit:
For now you can just include the library in every header that requires it (app, ball...).
But you may try something more complicated like MVC. And since it's a graphics library you can create a View and write all your view management there, like opening the window drawing the model etc..
What you do in MVC is a complete separation between model(game, ball) and the view, since you can display the model in different ways, one in 2D and another in 3D, each may use different library and view but the model is still the same.
There are a lot of designs and no correct one, as long as it easy to understand and maintain/add features it's a good design.
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.
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.