This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 4 years ago.
So I just began programming in c++ and I am planning to make a small game as my first project (with the SDL library).
So I have this really small piece of code in a header file that gives me an error that I can not solve.
main.h
#include "Screen.h"
#include "MainGame.h"
Screen* screen = nullptr; //main.h line 8
Screen.h
#pragma once
#include "SDL.h"
#include <string>
#include <stdio.h>
#include <iostream>
#include "GameState.h"
#include "Game.h"
using namespace std;
class Screen
{
public:
Screen(string name, int width, int height, GameState* state);
~Screen();
SDL_Window *window;
SDL_Surface *screen;
SDL_Renderer *renderer;
};
MainGame.h
#pragma once
#include "GameState.h"
#include <stdio.h>
class MainGame :
public GameState
{
public:
MainGame();
~MainGame();
void start();
void update();
void render();
void stop();
};
Game.h
#pragma once
#include "GameState.h"
#include "Screen.h"
#include "SDL.h"
#include "main.h"
class Game
{
public:
GameState* activestate;
Game(GameState state);
~Game();
void changeState(GameState newState);
bool isRunning;
void handleEvents();
void update();
void render();
void stop();
};
GameState.h
#pragma once
class GameState
{
public:
GameState();
~GameState();
virtual void start();
virtual void update();
virtual void stop();
virtual void render();
};
And it gives this errors:
Error C2143 syntax error: missing ';' before '* main.h 8
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int main.h 8
What do these errors mean and how do I solve them?
The error comes from your circular dependency. Some file includes Screen.h. Screen.h includes Game.h. Game.h includes main.h. main.h needs Screen.h but because of pragma once it can't include it. So it doesn't know class Screen. Either remove circular dependency (better solution if possible, here it's possible):
Remove #include "main.h" in Game.h
or use forward declaration:
Write class Screen; in main.h:7
Related
This question already has answers here:
How are circular #includes resolved?
(4 answers)
Closed 2 years ago.
I get GameObject: base class undefined while trying to compile. I don't see anything wrong. I have a parent-child relationship between GameObject and player:
GameObject.h
#pragma once
#include "Game.h"
class GameObject
{
protected:
int x, y;
SDL_Texture* objTexture;
SDL_Rect srcRect{}, destRect{};
public:
GameObject(const char* textureSheet, int p_x, int p_y);
~GameObject();
void Update();
void Render();
};
Player.h
#pragma once
#include "GameObject.h"
class Input;
class Player : public GameObject
{
private:
Input* input{ nullptr };
public:
Player(Input * p_input);
~Player();
void Update();
};
This is Game.h
#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include "TextureManager.h"
#include "Player.h"
#include "Map.h"
#include "Input.h"
class Player;
class Map;
class Input;
class Game
{
private:
SDL_Window* window{ nullptr };
Player* player{ nullptr };
Input* input{ nullptr };
Map* map{ nullptr };
bool isRunning = false;
public:
Game();
Game(const char* title, int xPos, int yPos, int width, int height, bool fullscreen);
~Game();
void HandleEvents();
void Update();
void Render();
void clean();
bool running() { return isRunning; };
static SDL_Renderer* renderer;
};
most of the discussion I have seen says that this is due to some repeated includes which create circular dependencies, but I don't see any problem with that. is this something to do with the game class?
It would help if you gave us the exact error message and pointed to the line number.
I suspect this is because your GameObject has a constructor that requires arguments but your Player class does not provide these arguments in its constructor initialization list.
But this is just a guess.
A new guess!
The #include "Game.h" in your GameObject.h is the problem.
Only ever include what you use, and never create circular references even if you use #pragma once That pragma doesn't do what some people think it does.
Instead of Game.h include the SDL headers you require.
Whenever possible remove header includes from header files and use forward declarations of anything that is a pointer. Include the header for the concrete definitions only in your source files (the .cpp files).
You really want to avoid the problem of including one header and having it pull in a huge web of 500 other include files.
You are going to need the SDL header in order to use SDL_Rect though.
The easy way is to forward declare the missing class prototypes.
class SDL_Texture;
class SDL_Rect;
As you have already started on in Player.h
A more defensive way is to always include all headers needed in every source file.
#include <SDL.h>
or another SDL header.
And you have already solved the circular include with the
#pragma once
There is a C2238 error in the PauseMenu header file on the line: Game* game;
It says that ';' is an unexpected token, as well as: C2143 syntax error: missing ';' before '*' on the same line; I have no idea what's wrong in those files, I thought both files are correct.
PauseMenu.h Header File:
#pragma once
#include "EventHandler.h";
#include "MousePressEvent.h";
#include "RectElement.h";
#include "Engine.h";
class PauseMenu :
public EventHandler
{
public:
PauseMenu();
void Show();
void Hide();
void onEvent(Event* event);
void onEvent(MousePressEvent* event);
Game* game;
private:
RectElement* background;
RectElement* resume;
RectElement* options;
RectElement* quit;
bool visible = false;
};
Game.h Header File
#pragma once;
#include "Engine.h";
#include <ctime>;
#include "GameLayer.h";
#include "TextElement.h";
#include "HUDManager.h";
#include <windows.h>;
#include "Collider.h";
#include "CircleCollider.h";
#include "BoxCollider.h";
#include "MouseMoveEvent.h";
#include "CollisionShapeHitEvent.h";
#include "EventHandler.h";
#include "MainMenu.h";
#include "FpsCounter.h";
#include "PauseMenu.h";
#define PI 3.14159265358979323846264338327950288;
class Game :
public EventHandler
{
public:
Game(bool dev);
~Game();
void onEvent(Event* event);
void onEvent(MouseMoveEvent* event);
void onEvent(KeyPressEvent* event);
void onEvent(KeyReleaseEvent* event);
void onEvent(CollisionShapeHitEvent* event);
MainMenu* mainMenu;
PauseMenu* pauseMenu;
private:
Player* player;
Engine* engine;
};
Remove the semicolons after your #includes and #defines. In fact: Remove all semicolons after lines beginning with # if you can't find a reason for them to be there.
And I doubt that you need all those files included in game.h. But you are missing game.h in pausemenu.h or a forward declaration of Game:
class Game;
I guess you have some circular depenency between headers.
To solve it, you can use forward declaration for class Game; in PauseMenu.h Header File before the class PauseMenu.
I guess this way you still maight get other errors but you'll skip the mentioned one
Try to put destructor ~PauseMenu(){}
at the end of class.
I get the following error message after compiling my code:
Error C4430 missing type specifier - int assumed. Note: C++ does not
support default-int on line 21
I dont really know why the AssetManager retrieves that error, since I included everything needed...
My code:
game.hpp
#pragma once
#include "SDL.h"
#include "SDL_image.h"
#include <iostream>
#include <vector>
#include "AssetManager.hpp"
class Game {
public:
Game();
~Game();
void init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
void handleEvents();
void update();
bool running() { return isRunning; };
void render();
void clean();
static AssetManager* assets;
////////
}
AssetManager.hpp
#pragma once
#include <map>
#include <string>
#include "TextureManager.hpp"
#include "Vector2D.hpp"
#include "ECS.hpp"
class AssetManager {
public:
AssetManager(Manager* man);
~AssetManager();
void AddTexture(std::string id, const char* path);
SDL_Texture* GetTexture(std::string id);
private:
Manager* manager;
std::map<std::string, SDL_Texture*> textures;
};
I think this is a problem of circular dependency. Try forward declaration for AssetManager something like this:-
Class AssetManager; instead of #include "AssetManager.hpp" in game.hpp
So, I'm having what is likely a pretty simple problem, but I can't seem to figure out what is causing it.
I have a C++ class called "Game" consisting of a class declaration in Game.h
and a source definition in Game.cpp.
I have included "Game.h" in my "Game.cpp", but for some reason Visual Studio doesn't seem to recognize the class declarations within Game.h.
I'd appreciate any help I could get trying to figure out why this is the case, and why I am getting the following errors:
'MyCharacter' : undeclared identifier and 'HandleKeyPressed' : identifier not found.
Game.h:
------------------------------------------------------------------------------------------------------------------
#pragma once
#ifndef Game_Header
#define Game_Header
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "Character.h"
#include "FloorPlatform.h"
class Game
{
public:
Game();
~Game();
int Run();
void HandleKeyPressed(sf::Keyboard::Key);
Character MyCharacter;
};
#endif // !Game_Header
Abridged Game.cpp
#include "Game.h"
Game::Game()
{
}
Game::~Game()
{
}
int Run(){
sf::RenderWindow MainGameWindow(sf::VideoMode::getDesktopMode(), "A Test Game");
//Start Game Loop
while (MainGameWindow.isOpen()){
while (MainGameWindow.pollEvent(event)){
//Handle some other events here...
if (event.type == sf::Event::KeyPressed){
HandleKeyPressed(event.key.code);
}
}
MainGameWindow.clear(sf::Color::White);
MyCharacter.Instance.Circle.setPosition(MyCharacter.PlayerLocation);
MainGameWindow.draw(MyCharacter.Instance.Circle);
MainGameWindow.display();
}
return 0;
}
void HandleKeyPressed(sf::Keyboard::Key PressedKey){
switch (PressedKey)
{
case sf::Keyboard::A:
MyCharacter.PlayerLocation.x -= 16;
break;
}
}
Full code can be found here:
http://pastebin.com/x6KhDxgL
Thanks in advance for any help I can get with this.
Try
int Game::Run()
instead of
int Run()
in Game.cpp, the same for HandleKeyPressed, because it's the method of the Game class. Depending on your Character.h you may need to initialize MyCharacter, too.
void HandleKeyPressed(sf::Keyboard::Key PressedKey){
In Game.cpp should be
void Game::HandleKeyPressed(sf::Keyboard::Key PressedKey){
Same for int run()
I'm having a problem with circular dependencies, I suppose this is a design flaw from introducing the Game class in the wrong way.
Game.h:
#pragma once
#include <SFML\Graphics.hpp>
#include "GameScreen.h"
#include "TitleScreen.h"
class Game
{
protected:
sf::RenderWindow window;
GameScreen* CurrentGameScreen;
TitleScreen Title;
public:
Game(void);
~Game(void);
sf::RenderWindow getWindow(void);
void Run();
void Close();
};
GameScreen.h:
#pragma once
#include "Game.h"
class GameScreen
{
public:
GameScreen(void);
~GameScreen(void);
virtual void LoadAllResources() {};
virtual void DrawScreen(Game* game) {};
virtual void Update(Game* game) {};
};
TitleScreen.h:
#pragma once
#include <SFML\Graphics.hpp>
#include "GameScreen.h"
class TitleScreen : public virtual GameScreen
{
private:
sf::Texture title_screen;
sf::Sprite titleScreen;
sf::Font font;
sf::Text menuExit;
public:
TitleScreen(void);
~TitleScreen(void);
void LoadAllResources();
void DrawScreen(Game* game);
void Update(Game* game);
};
Then there's the main file:
#include "Game.h"
int main()
{
Game game;
game.Run();
//sf::RenderWindow window(sf::VideoMode(800, 600), "Test");
//GameScreen* currentScreen;
//TitleScreen titleScreen;
//currentScreen = &titleScreen;
//while (window.isOpen())
//{
// currentScreen->Update(&window);
// currentScreen->DrawScreen(&window);
//}
return 0;
}
GameScreen.h and TitleScreen.h raise a handful of C2061. From what I understand these are caused by circular dependencies between Game.h and Gamescreen.h.
TitleScreen.h is giving me error C2504: 'GameScreen' : base class undefined.
Game.h: on lines 12 and 13, give C2143: syntax error : missing ';' before '*', although I'm not sure where this is coming from and my IDE is not giving me any syntax errors.
If I remove the #include statement from GameScreen.h and substitute it with a forward declaration class Game; (which I guess breaks the circular dependency?) most of the above is solved, but TitleScreen.cpp throws a set of C2027, C2227 and C2228 (undefined type, left of -> and left of .) every time I try to access a Game object. IntelliSense points out that a pointer to an incomplete class is not allowed.
I got it working before introducing the Game class - DrawScreen() and Update() would take as argument a pointer to window (sf::RenderWindow* window). There's part of the old code left in main.cpp.
In the GameScreen.h you should declare the Game class instead of including its whole header file, so this:
class Game;
instead of:
#include "Game.h"