Base class undefined and fatal error C1903 - c++

I'm writing Monopoly game with C++ and SFML. My application already has around 20 classes and they work together pretty well but I can't find solution for one problem. First I need to show you a bit of my code, I'm sorry if I post too much code (Ill try to paste simple minimum), but problems happen all accross my application once I add 1 line of code - #include "GameEngine.h" into Field.h and I dont really know what. Let's start with heart of application, GameState class that has GameLoop inside
class GameState : public State {
sf::Clock m_clock;
sf::Sprite m_background;
GameEngine m_gameEngine;
public:
GameState();
void initialise();
void handleUserInput();
void update(sf::Time);
void draw();
};
GameState::GameState(std::shared_ptr<ApplicationData> data) : m_gameEngine(2, "John", "Richard") {
//2 players named John and Richard, just for tests now
}
Then class that handles all the logic, GameEngine
class GameEngine {
//players
std::vector<Player> m_players;
int m_numberOfPlayers;
int m_activePlayer = 0;
//game objects
GameBoard m_gameBoard;
public:
GameEngine(int, std::string, std::string);
GameBoard& getBoard() { return m_gameBoard; }
Player& getActivePlayer() { return m_players[m_activePlayer]; }
};
For now, it just creates two players
GameEngine::GameEngine(int numberOfPlayers, std::string playerOneName, std::string playerTwoName)
: m_numberOfPlayers(numberOfPlayers), m_firstDice(FIRST_DICE_POSITION_X, FIRST_DICE_POSITION_Y),
m_secondDice(SECOND_DICE_POSITION_X, SECOND_DICE_POSITION_Y) {
m_players.push_back(Player(playerOneName, sf::Color::Red, -5, 0));
m_players.push_back(Player(playerTwoName, sf::Color::Blue, -5, 0));
}
Player class is nothing special, few variables and getter and setter functions
class Player {
int m_positionID = 0;
std::string m_name;
sf::CircleShape m_token;
};
Another significant part is GameBoard
class GameBoard {
std::array<std::shared_ptr<Field>, BOARD_SIZE> m_board;
public:
GameBoard();
~GameBoard() = default;
std::shared_ptr<Field>& getField(size_t index) { return m_board[index]; }
};
And finnaly Field where all the problems start
class Field {
protected:
int m_positionID;
float m_positionX;
float m_positionY;
bool m_buyable;
public:
Field() {}
Field::Field(int positionId, float positionX, float positionY, bool buyable) :
m_positionID(positionId), m_positionX(positionX), m_positionY(positionY), m_buyable(buyable) { }
virtual ~Field() = default;
virtual void calculateCharge(GameEngine&) = 0;
};
Field is base class for all my fields in game like Property, Start, GoToJail, etc. I want something like that: player rolls the dice, he is moved to new position, this position is checked (inside GameEngine)
m_board.getField(m_gameEngine.getActivePlayer().getPositionID())->calculateCharge();
Now calculateCharge() will perform a bit different action for every class, simple runtime polymorphism, but I want this function to actually call some functions from inside GameEngine, thats why I want to pass GameEngine& into this function, but once I '#include GameEngine.h' into 'Field.h', I got
error C2504: 'Field': base class undefined
followed by several errors from derived classes, that they cannot access members (which are protected), etc, whole inheritance isnt working anymore, and after few errors I got
fatal error C1903: unable to recover from previous error(s); stopping
compilation
I tried to add forward declaration but it doesnt help. I dont really know how to fix this.

Related

How can I create an instance of a variable in an abstract class

I handed in a remake of an old game in C++ using SDL2 for a programming course that I took, I passed but the professor left me some feedback and there is one part that I couldn't understand. It made sense when he said it and when I tried implementing it I got stuck.
I have an Enemy class which is an abstract class and then many different enemies that inherit from that class. The issue is that when I am creating an enemy I have to pass in its constructor my ProjectileManager* instance that I have created in my main controlling file called Game.cpp. He said that since all enemies need the ProjectileManager it would be smarter to just add it in the Enemies class as protected and have the other children inherit it.
The issue is that the instance is created in the Game.cpp and I have to pass that specific instance since that is the one that I am Drawing and Updating for. Is there a way to do that?
Edit: Here is some of the code
Game.cpp:
void Game::Initialize()
{
m_pProjectileManager = new ProjectileManager();
}
The projectile manager is what Updates and Draws all the projectiles as well as their hit logic etc.
It has an array that manages all the projectiles.
Every time an enemy wants to shoot it would access the projectile manager (that I passed in its constructor) and trigger the shoot function of the specific enemy:
void Plant::Shoot(const Point2f& target)
{
if (m_CanShoot)
{
m_CurrentState = Plant::PlantState::shooting;
m_pProjectileManager->AddProjectile((new PlantProjectile(Point2f{ m_Shape.left, m_Shape.bottom }, target)));
m_CanShoot = false;
m_TimeSinceLastShot = 0;
}
}
Finally this is the Enemy class that I have right now:
class Enemies
{
public:
virtual ~Enemies() = 0;
virtual void Update(float elapsedSec, const Point2f& playerPos, Level& level) = 0;
virtual void Draw() const = 0;
virtual Rectf GetShape() const = 0;
virtual float GetHealth() const = 0;
virtual void Damage(float damage) = 0;
protected:
ProjectileManager* m_pProjectileManager;
};
If there is only ever one ProjectileManager object in the entire game, there are two "easy" ways to accomplish this, and both have some drawbacks.
First, you could make it a singleton:
class ProjectileManager
{
// stuff....
static ProjectileManager* instance()
{
static ProjectileManager one;
return &one;
}
};
// Game.cpp
void Game::Initialize()
{
// m_pProjectileManager = new ProjectileManager();
m_pProjectileManager = ProjectileManager::instance();
}
// Enemy impl
void Plant::Shoot(const Point2f& target)
{
if (m_CanShoot)
{
m_CurrentState = Plant::PlantState::shooting;
ProjectileManager::instaince()->AddProjectile((new PlantProjectile(Point2f{ m_Shape.left, m_Shape.bottom }, target)));
m_CanShoot = false;
m_TimeSinceLastShot = 0;
}
}
Or you could make it static in Enemy, and provide a function to set it:
class Enemy
{
public:
static SetProjectileManager(ProjectileManager* projectile_manager)
{
m_pProjectileManager = projectile_manager;
}
protected:
static ProjectileManager* m_pProjectileManager;
};
// Game.cpp
void Game::Initialize()
{
m_pProjectileManager = new ProjectileManager();
Enemy::SetProjectileManager(m_pProjectileManager);
}
Without seeing the entire codebase it's hard to know which is the better (of these two) recommendations. Neither is perfect by any means. Singletons have a lot of drawbacks and I hesitate to recommend them much anymore. Static class members are perhaps less of a code smell.
In any case, the best path forward is likely a refactor to pass to the Enemy constructor.
Some further reading:
What are drawbacks or disadvantages of singleton pattern?
Why using static namespace/class member variables is a bad idea in C++?

Why can't the compiler find the superclass's method?

I'm trying to do class inheritance in C++, but it obviously works very differently than in Python.
Right now, I have two classes, one called Player that is the base class, and another one called HumanPlayer that's the subclass.
The Player class is an abstract class that has two ways of working.
The first is that it acts like a singleton. It has one static function called make_move that people can call with an int and a TicTacToeGame&, and it will make a move for the player with that int as the player's number in that game of TicTacToe.
The second is that it works as a class for creating objects that have a player number as a property. So, if you construct an object with the class, you should get back an object with a player_number property. Then, if you call the make_move function with just a TicTacToeGame& on the object, it will automatically plug in its player number and use the static class method to make the move in the game.
I want the same functionality for HumanPlayer, except I just want to have to write a new static function for HumanPlayer, and that's it, since the other functionality remains the same.
Here's the code:
#include <iostream>
#include <string>
using namespace std;
class TicTacToeGame {
};
class Player {
public:
static void make_move(int player_number, TicTacToeGame& game);
protected:
int player_number;
public:
explicit Player(int player_number_param) {
player_number = player_number_param;
}
public:
void make_move(TicTacToeGame& game) {
return make_move(player_number, game);
}
};
class HumanPlayer: public Player {
public:
static void make_move(int player_number, TicTacToeGame& game) {}
public:
HumanPlayer(int player_number_param): Player(player_number_param) {}
};
int main()
{
TicTacToeGame game;
HumanPlayer human_player = HumanPlayer(2);
human_player.make_move(game);
return 0;
}
I learned recently that subclasses don't inherit constructors, so it turns out I have to write both a new static function and a constructor, which I have done.
However, whenever I initialize a new HumanPlayer object, the compiler can't seem to find a match for the make_move(TicTacToeGame&) method, and I'm not sure why.
The specific error message I'm getting is
C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp: In function 'int main()':
C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp:41:29: error: no matching
function for call to 'HumanPlayer::make_move(TicTacToeGame&)'
human_player.make_move(game); ^ C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp:29:15: note: candidate:
static void HumanPlayer::make_move(int, TicTacToeGame&) static void
make_move(int player_number, TicTacToeGame& game) {} ^~~~~
C:\Users\London\Desktop\Python
Programs\LearningC++\FirstProgram_SO.cpp:29:15: note: candidate
expects 2 arguments, 1 provided
How can I get the HumanPlayer class to work in the same way the Player class does?
The redefinition of the static function with the same name is hiding the one you want to use.
Either rename it differently or add
public:
using Player::make_move;
Note that unlike Java you don't need to repeat public: before every function, the same visibility applies as long as you don't change it.
class YourClass {
public:
void foo1(); // public
void bar1(); // also public
protected:
void foo2(); // protected
void bar2(); // also protected
};

Calling a function of another class from another class

I am working on a project where there are two player objects and one game object.
The two player objects need to access the game object's function display(), but i have no idea how this could be done.
Below is a snippet highlighting the core issue:
class Game
{
public:
Game() {}
display() {...}
...
};
class Player
{
public:
Player() {}
void input()
{
...
// display();
...
}
};
Please suggest a way to solve this problem. if you find fundamental issue with this design pattern, feel free to correct that!
Why not?
void input()
{
game.Display();
}
but probably, you need to pass a Player object to it. Thus, change it this way:
class Player; // FORWARD declaration
class Game
{
public:
Game() {}
void display(Player& player); // Implement elsewhere not here.
// Another way
void display(Player* player = NULL); // Implement elsewhere not here.
...
};
...
void input()
{
game.Display(*this);
game.Display(this); // another way
}

c++ polymorphism - accessing inhertied variables

playersystem and rocketsystem inherit from system, playersystem contains pointer to rocketsystem. im getting an error when i try to access anything that is in system that rocketsystem is supposed to inherit. the runtime error is "expression cannot be evaluated" i set a breakpoint in visual studio, hovered the mouse over the position vector and it said that.
edit: for posterity this is what i was doing, and it turns out it is working, i was just setting th rocketsystem pointer to null for some reason
class Vector2D
{
public:
float x;
float y;
Vector2D(float x_, float y_) :x(x_),y(y_){}
};
class System
{
protected:
vector<Vector2D> position;
public:
void addEntity(Vector2D newPos)
{
position.push_back(newPos);
}
};
class projectile :public System
{
public:
void createRocket(Vector2D pos)
{
addEntity(pos);
}
};
class player : public System
{
public:
projectile* rocketSystem;
void init(projectile* rocketsys){rocketSystem = rocketsys;}
void fireRocket(Vector2D pos)
{
rocketSystem->createRocket(pos);
}
};
int main (int argc, char * const argv[])
{
player* PlayerSystem = new player;
projectile* RocketSystem = new projectile;
PlayerSystem->init(RocketSystem);
PlayerSystem->fireRocket(Vector2D(0,0));
return 0;
}
I'm going to use my psychic powers and guess that the System class doesn't have a createRocket() member. Since playersystem has a System *rocketSystem and not a rocketsystem *rocketSystem, the only functions that can be invoked on the rocketSystem member are those declared in the System class. It has to be a rocketsystem* if you want to be able to call that function, and the rocketsystem class has to be declared before the playersystem::fireRocket function is defined.

C++ - "Member function not declared" in derived class

I have a problem in MSVC++ 2008 where VS2008 is throwing this compile error:
error C2509: 'render' : member function not declared in 'PlayerSpriteKasua'
Now, what's confusing me is that render() is defined, but in an inherited class.
The class definition works like this:
SpriteBase -Inherited By-> PlayerSpriteBase -Inherited By-> PlayerSpriteKasua
So, a pared-down version of SpriteBase.h is the following:
class SpriteBase {
public:
//Variables=============================================
-snip-
//Primary Functions=====================================
virtual void think()=0; //Called every frame to allow the sprite to process events and react to the player.
virtual void render(long long ScreenX, long long ScreenY)=0; //Called every frame to render the sprite.
//Various overridable and not service/event functions===
virtual void died(); //Called when the sprite is killed either externally or via SpriteBase::kill().
-snip-
//======================================================
};
PlayerSpriteBase.h is this:
class PlayerSpriteBase : public SpriteBase
{
public:
virtual void pose() = 0;
virtual void knockback(bool Direction) = 0;
virtual int getHealth() = 0;
};
And finally, PlayerSpriteKasua.h is this:
class PlayerSpriteKasua : public PlayerSpriteBase
{
public:
};
I know there are no members in it yet, but that's simply because I hadn't gotten to adding them. Same goes for PlayerSpriteBase; there's other stuff left to go in to it.
The code in PlayerSpriteKasua.cpp is this:
#include "../../../MegaJul.h" //Include all the files needed in one go
void PlayerSpriteKasua::render(long long ScreenX, long long ScreenY) {
return;
}
void PlayerSpriteKasua::think() {
return;
}
int PlayerSpriteKasua::getHealth() {
return this->Health;
}
When I type, say, void PlayerSpriteKasua::, Intellisense pops up listing all the members of PlayerSpriteBase and SpriteBase just fine, but on compile it fails like I said above.
Is there any particular reason I'm getting this error?
PlayerSpriteBase.cpp is empty and has nothing in it as of yet.
SpriteBase.cpp has plenty of function definitions for SpriteBase, and uses the same format as PlayerSpriteKasua.cpp:
void SpriteBase::died() {
return;
}
is an example.
In PlayerSpriteKasua.h you need to re-declare whatever methods you're going to override/implement (without the "=0" to say that those methods are not abstract anymore). So you need to write it like follows:
class PlayerSpriteKasua : public PlayerSpriteBase
{
public:
virtual void think();
virtual void render(long long ScreenX, long long ScreenY);
virtual int getHealth();
};
...or did you omit that to keep your post shorter?
You need to provide a declaration for PlayerSpriteKasua::render() in your class definition. Otherwise, other translation units including your PlayerSpriteKasua.h wouldn't be able to tell that you'd provided a definition, and would be forced to conclude that PlayerSpriteKasua can't be instantiated.
You need to redeclare the members of SpriteBase that you are going to implement in PlayerSpriteKasua in the declaration of PlayerSpriteKasua in PlayerSpriteKasua.h.