C++ Base class undefined while compiling [duplicate] - c++

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

Related

C++ - Circular dependency between 3 Classes

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.

C++ Making Pointer of Class type [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm new to C++ and can't figure out this error.
I'm trying to make a pointer type for the class Player. From all of the tutorials I've seen, this should be the proper syntax for declaring a pointer of type Player in a header file.
Player* player = new Player;
[EDIT, accidentally posted before finished]
But I get the error " must use 'class' tag to refer to type 'Player' in this scope". I've used #include "Player.h".
What's going on here?
EDIT
All of these give the same error
Player* player;
Player* player = new Player;
Player* player = new Player();
This header file for Player
#ifndef PLAYER_H
#define PLAYER_H
#include <vector>
#include <string>
#include <iostream>
#include "Item.h"
#include "GlobalDefs.h"
class Player
{
public:
// constructor
Player( void );
// destructor
virtual ~Player( void );
inline gold_t GetGold( void )
{
return gold;
}
void AddGold(gold_t amount);
void RemoveGold(gold_t amount);
std::string GetInventoryString(void);
void AddItem(Item);
private:
gold_t gold;
Item item;
std::vector <Item> inventory;
};
#endif /* PLAYER_H */
This is the header file where the pointer (Player* player = new Player;) is being defined.
#ifndef STOREAREA_H
#define STOREAREA_H
#include "AreaAbstract.h"
#include "Player.h"
#include <iostream>
class StoreArea : public AreaAbstract{
typedef void (StoreArea::*AreaInput)( void );
public:
StoreArea(*Player);
StoreArea();
~StoreArea();
void PrintAreaText();
bool RecieveInput(std::string);
protected:
void PurchaseHelm();
std::map <std::string, AreaInput> areaInputMap;
Player* player;
};
#endif /* STOREAREA_H */
It sounds like you have a variable or other identifier (other than the class) named Player somewhere, and the error message is suggesting to use:
Player* player = new class Player;
to disambiguate between the two Players.
The simplest solution would be the rename the non-class Player to something else, e.g. player.

C++: Inclusion inside inclusion

The title might not be very clear, it's a bit more complex than that. I searched the web for something like my problem but I did not find anything that could help me.
This is not about infinite looping inclusions, I already put preprocessor directives to avoid that.
I have two classes Monster and Character, respectively declared in their own header files, monster.hpp and character.hpp, and respectively implemented in their own source files, monster.cpp and character.cpp.
The problem now is that both classes need each other to work.
monster.hpp :
#ifndef INCLUDE_MONSTER_HPP
#define INCLUDE_MONSTER_HPP
#include "character.hpp"
class Monster
{
private: //Atributes
public: //Methods
void attackM(Monster& id);
void attackC(Character& id);
};
#endif //MONSTER_HPP_INCLUDED
character.hpp :
#ifndef INCLUDE_CHARACTER_HPP
#define INCLUDE_CHARACTER_HPP
#include "monster.hpp"
class Character
{
private: //Attributes
public: //Methods
void attackM(Monster& id);
void attackC(Character& id);
};
#endif //CHARACTER_HPP_INCLUDED
and the main.cpp :
#include <iostream>
#include "character.hpp"
#include "monster.hpp"
using namespace std;
int main(int argc, char **argv)
{
//Whatever
return 0;
}
And I get this error from the compiler :
In file included from character.hpp:7:0,
from main.cpp:3:
monster.hpp:24:16: error: 'Character' has not been declared
void attackC(Character& id);
(the line and column numbers may be wrong)
From what I understand, when monster.hpp is included into character.hpp, the compiler sees that the class Monster uses the class Character, which is not declared yet right at the moment when monster.hpp is included into character.hpp.
And I don't know how to fix that.
Any ideas ?
The way this works is that the header files of char and monster do not include each other. Instead you forward declare the classes and include the headers within the CPP files.
So basically replace #include "monster.hpp" in the.h with class Monster; and #include "monster.hpp" in the .cpp - and same for the other class.
See this question for more details:
What are forward declarations in C++?
#ifndef INCLUDE_MONSTER_HPP
#define INCLUDE_MONSTER_HPP
#include "character.hpp"
class Character;
class Monster
{
private: //Atributes
public: //Methods
void attackM(Monster& id);
void attackC(Character& id);
};
#endif //MONSTER_HPP_INCLUDED
You need to use a forward declaration. See: http://en.wikipedia.org/wiki/Forward_declaration
Basically, the compiler doesn't know what a "Character" is. You temporarily indicate that it's something you can point to by adding the following stub to Character.hpp:
class Character;
Use predeclaration in *.h:
class Character;
class Monster;
use in *cpp the includes:
#include "character.h"
#include "monster.h"
Or put everything in one *.hpp with predeclaration.

C++: circular dependency issue

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"

"'SpaceShip' does not name a type" even though SpaceShip certainly is a type [duplicate]

This question already has answers here:
C++ Does not name to a type
(2 answers)
Closed 10 years ago.
I'm working on an Asteroids game as a way to teach myself some programming stuff, and I'm getting this error that one of my classes doesn't name a type.
I have a SpaceShip class that inherits from Entity class (both are defined) and I have a Bullet class that inherits from Entity. I'm trying to put a SpaceShip Member into the Bullet Class as a way of telling who shot the bullet, but it keeps telling me that "'SpaceShip' does not name a type".
Here's some code:
spaceship.h
class SpaceShip : public Entity
{
private:
int lives;
int score;
int animationRow;
int shotsFired;
public:
SpaceShip();
void Init(SDL_Surface *image = NULL);
void Destroy();
void Update();
void Render( SDL_Surface *screen );
...
};
bullet.h
#ifndef BULLET_H
#define BULLET_H
#include <SDL/SDL_gfxPrimitives.h>
#include "entity.h"
#include "spaceship.h"
#include "Globals.h"
class Bullet : public Entity
{
private:
SpaceShip* owner;
public:
Bullet( SpaceShip* ship );
void Update();
void Render( SDL_Surface *screen );
void Destroy();
void Collided(int objectID);
};
#endif // BULLET_H
Why isn't it finding the SpaceShip type?
It seems (based on clarification in comments) that your code has Circular dependencies. SpaceShip depends on Bullet which in turn depends back on SpaceShip. You need to re-factor your code to remove circular dependencies.
Usually this can be accomplished easily with Forward decleration but more advanced methods (more OOP correct) include interfaces, callbacks or better yet events (signals)