I have a general GameState class:
#pragma once
#include "GameContext.h"
class GameContext;
class GameState
{
private:
protected:
public:
GameState(GameContext* context);
GameContext* gameContext = nullptr;
virtual void update(float deltaTime) = 0;
virtual void draw(float deltaTime) = 0;
};
which is suppose to be the base for other GameState's. I have attempted to implement a derived class of GameState:
#pragma once
#include <iostream>
#include "GameState.h"
#include "GameContext.h"
class GameStateMenu : public GameState
{
private:
protected:
public:
GameStateMenu(GameContext* gameContext);
void update(float deltaTime);
void draw(float deltaTime);
};
I am getting a error in the implementation of GameStateMenu at
class GameStateMenu : public GameState
where it says
'GameState': base class undefined
I have googled and gone through my code for a good few hours now and can still not figure it out. I feel like it should know what GameState is but I can't figure out why it doesn't.
(If the current code is not enough to figure it out the rest is available HERE)
As I suspected the problem was a circular dependency that I had also forward declared which meant that I did not see an error about it when compiling. Removing the #include "GameContext.h" in GameState.h removed the one circular dependecy that was causing the problem.
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
I am aware that this error usually occurs due to the parent class having a virtual function and that virtual function not being defined in the subclass.
I have , to my knowledge at least defined all the functions bar the function that is supposed to be the signal.
This the .h file for the class
#ifndef HREAD_H
#define HREAD_H
#include "package.h"
#include <QThread>
class hread:public QThread
{
Q_OBJECT
signals:
void transfer(structureData* pkg);
public:
hread();
virtual ~hread();
private:
structureData Send;
bool abort,restart;
protected:
void run() override;
};
#endif // INPUTTHREAD_H
This is my main .cpp file
hread::hread()
{
MutexSend.lock();
restart=false;
abort=false;
MutexSend.unlock();
}
hread::~hread()
{
}
void hread::run()
{
emit transfer(&pkg);
}
I can't quite pinpoint why I got this error.
I have three classes, 2 of which rely on the functionality of each other, and one which contains pointers to and is included in both:
Player:
#pragma once
#include <SFML\Graphics.hpp>
#include "RenderableObject.h"
//#include "Renderer.h"
class Renderer;
class Player : public RenderableObject
{
public:
Player(int size, Renderer* renderer);
~Player();
void render();
void setX(int x);
void setY(int y);
int getX();
int getY();
void setVelX(float x);
void setVelY(float y);
float getVelx();
float getVely();
int getSize();
private:
int size;
int x;
int y;
float velx;
float vely;
Renderer* ren;
};
GameManager:
#pragma once
#include "Player.h"
class Renderer;
class GameManager
{
public:
GameManager(Renderer* r);
~GameManager();
Player* getBall();
private:
Player* ball;
};
Renderer:
#pragma once
#include <SFML\Graphics.hpp>
#include "GameManager.h"
#include "Player.h"
class Renderer
{
public:
Renderer(GameManager* game);
~Renderer();
sf::RenderWindow* getWindow();
void draw();
void renderCircle(int size, int x, int y);
void renderSquare(int size, int x, int y);
private:
sf::RenderWindow* win;
GameManager* game;
Player* ball;
};
I suspect there is some sort of circular dependency going on here. I managed to reduce the 60 odd errors down to 3, by adding "class Renderer;" to the Player header file. However, I'm now receiving "Use of undefined type" errors.
It might help to give a higher level view of what I want to achieve:
The GameManager object should hold an instance (maybe more) of player. This GameManager object is shared between subsystems such as Renderer so they all have access to the same resources.
The Renderer object should be able to call the Player object's (retrieved from the GameManager object) render() function, which in turn should call back to the Renderer object's renderCircle() object.
I'm hoping this is a simple case of re-arranging the includes, without having to re-design what I've already done.
In a header file, where you only declare variables that are pointers or references, all the compiler needs to know is that a class exists, nothing more. It doesn't need to know how big it it, or what members the class have. Therefore it's enough with a forward declaration.
However, in the source files where the variable is used, objects are created, and member functions are called, then the compiler need the full definition which means you have to include your whole header file.
Taking your code, simplified:
Player.h
#pragma once
class Renderer;
class Player
{
public:
Player(Renderer*);
private:
Renderer* ren;
};
GameManager.h
#pragma once
class Renderer;
class GameManager
{
public:
GameManager(Renderer*);
private:
Renderer* ren;
};
Renderer.h:
#pragma once
class Player;
class GameManager;
class Renderer
{
public:
Renderer(GameManager*);
private:
GameManager* game;
Player* ball;
};
The above header files are about the same that you already have, with the exception that I used forward declarations in Renderer.h instead.
Now the Renderer.cpp source file, where the Player and GameManager objects are actually created and used, we need the full definition from the header files:
#include "Renderer.h"
#include "Player.h"
#include "GameManager.h"
Renderer::Renderer(GameManager* game)
: game(game), ball(new Player)
{
}
// Other functions that calls member function in the `man` and `ball` objects
Of course, you need to #include "Renderer.h" in the Player.cpp and GameManager.cpp source files.
If you have other errors, they are because of other things you done, not because of the circular dependencies, as those have been solved with the forward declarations.
I have two classes: AbstractClass and SubClass.
This is basically my code (well, just some example code):
abstractclass.h
class AbstractClass
{
public:
AbstractClass();
void doSomething();
protected:
virtual void implementMe() = 0;
int a;
};
abstractclass.cpp
#include "abstractclass.h"
AbstractClass::AbstractClass(){}
void AbstractClass::doSomething()
{
implementMe(); // compiler error: "implementMe() was not declared in this scope"
a = 0; // same compiler error here...
}
subclass.h
#include "abstractclass.h"
class SubClass : public AbstractClass
{
public:
SubClass();
protected:
void implementMe();
};
subclass.cpp
#include "subclass.h"
SubClass::SubClass() {}
void SubClass::implementMe()
{
// do some stuff
}
In the AbstractClass, however, I keep getting a compiler error (for the virtual function as well as for the class variable):
implementMe() was not declared in this scope
The only way I found to get rid of this was to use forward-declaration:
void implementMe();
AbstractClass::doSomething()
{
implementMe();
}
I cannot believe that this is the correct way, though?
Thanks!
EDIT:
Ok, as my conceptual understanding of subclassing in C++ doesn't seem to be totally wrong (see the comments), I'm gonna share some of my original source code. Hopefully this will help to indentify the error.
This is my abstract / base class:
abstractenvironment.h
#ifndef ABSTRACTENVIRONMENT_H
#define ABSTRACTENVIRONMENT_H
#include <QObject>
class AbstractEnvironment : public QObject
{
Q_OBJECT
public:
AbstractEnvironment(QObject *parent = 0);
protected:
virtual void process() = 0;
quint32 counter;
private slots:
void handleTimeout();
};
#endif // ABSTRACTENVIRONMENT_H
abstractenvironment.cpp
#include "abstractenvironment.h"
#include <QTimer>
QTimer *myTimer;
AbstractEnvironment::AbstractEnvironment(QObject *parent) :
QObject(parent)
{
myTimer = new QTimer(this);
connect(myTimer, &QTimer::timeout, this, &AbstractEnvironment::handleTimeout);
myTimer->start(1);
counter = 0;
}
void handleTimeout()
{
process();
counter++;
}
And this is my subclass:
environment.h
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
#include "abstractenvironment.h"
class Environment : public AbstractEnvironment
{
Q_OBJECT
public:
Environment(Controller *controller, QObject *parent = 0);
protected:
void process();
};
#endif // ENVIRONMENT_H
environment.cpp
#include "environment.h"
Environment::Environment(Controller *controller, QObject *parent) :
AbstractEnvironment(controller, parent) {}
void Environment::process()
{
// do something
}
PS: I've learned from the first part of this question and tried to compile the source code above inside Qt with MinGW. I get exactly two error messages (as expected):
..\untitled\abstractenvironment.cpp: In function 'void handleTimeout()':
..\untitled\abstractenvironment.cpp:17:13: error: 'process' was not declared in this scope
..\untitled\abstractenvironment.cpp:18:5: error: 'counter' was not declared in this scope
In case you want to try it yourself, I've zipped the Qt project and uploaded it to my Dropbox (of course I will remove this file at some point but the code is exactly the same as in the post above --> it's just for the sake of convenience, so you don't have to copy-paste it yourself)
EDIT: You just changed your question. So I can't tell if your original text was your actual source code or not. Good rule of thumb, paste your actual code rather than paraphrase it (then de-identify or reduce it if needed).
ORIGINAL ANSWER:
implementMe(); // compiler error: "implementMe() was not declared in this scope"
That is because doSomething() isn't declared properly in AbstractClass. You "declared" it in the base class with:
doSomething();
The compiler doesn't recognize AbstractClass::doSomething() out of line definition so nothing inside the implementation is resolved to the class scope.
Change that to:
void doSomething();
just like in your derived class.
and
AbstractClass::doSomething()
{
implementMe();
}
to
void AbstractClass::doSomething()
{
implementMe();
}
UPDATE:
void handleTimeout()
{
process();
counter++;
}
is a global function. That isn't the class implementation. It should be:
void AbstractClass::handleTimeout()
{
process();
counter++;
}
In abstractenvironment.cpp you define void handleTimeout(), which is non-member function and does not relate to AbstractEnvironment class. Thus, it doesn't look for AbstractEnvironment::process() and AbstractEnvironment::counter, but for ::process() and ::counter instead (which are not declared, hence the error).
Change it to void AbstractEnvironment::handleTimeout() and it should compile.
I have a State class that is fully implemented as outlined below. I also have a PlayState class that inherits the State class, it too is fully implemented. My compile error is "playstate.h(6): error C2504: 'State' : base class undefined"
I have checked their order in Global.h, State.h appears before PlayState.h
CODE:
STATE.H
#pragma once
#include "Global.h"
class State
{
public:
State(void);
virtual ~State(void);
virtual void Input(INPUTDATA* InputData);
virtual void Logic(OBJECT go[], INPUTDATA* InputData);
virtual void Render(OBJECT go[]);
virtual void InitGame(OBJECT go[]);
virtual void LoadGraphics(void);
void Toggle();
bool IsEnabled();
private:
bool isEnabled;
};
PlayState.h
#include "Global.h"
class PlayState : public State
{
private:
#define UPDATESPEED 1000 // milliseconds between each update
// global variables
float camXAngle;
float camYAngle;
float camZoom;
int updatetime;
bool gameover;
float runspeed;
D3DLIGHT9 light;
SPRITE graphics;
SPRITE particleTexture;
MODEL terrain[2];
MODEL sky;
public:
PlayState();
~PlayState();
void Input(INPUTDATA* InputData);
void Logic(OBJECT go[], INPUTDATA* InputData);
void Render(OBJECT go[]);
void InitGame(OBJECT go[]);
void LoadGraphics(void);
};
Thanks
If some *.cpp includes "State.h" without "Global.h" somewhere before it then you will have the error that you've posted.
Because when "State.h" includes "Global.h" then "Global.h" does not include "State.h" (because of #pragma once) but it includes "PlayState.h" so in the end you have "PlayState.h" included before class State is defined.
Just don't make such weird circular inclusions.
If your Global.h already includes State.h and PlayState.h and in the order that State.h is placed before PlayState.h, then there is no reason to get the particular error(for the source code you have posted), unless except you are making some silly typo like missing a caps in State. Please check for typos! or there might be another reason to the problem.
You are building a circular dependency of includes, which should be avoided.
A simple solution might be to not include both includes, State.h and PlayState.h in Global.h.
Just include State.h inside PlayState.h and it should be fine. Global.h wont build up any circular dependencies that way.
#pragma once
#include "Global.h"
class PlayState : public State
What is "State"? That is what the compiler is complaining about.
You can't inherit from a class that has not been fully defined. Looking at the file PlayState.h, nowhere do you specify the State class.
CORRECTED CODE:
#pragma once
#include "State.h"
class PlayState : public State