Reputation: 53
I've been recently doing a lot of reading and decided to try and implement a simple State pattern to try and see how things fit together.
However, I've ran into an issue I've never come across before: The Scene's subclass (Start) doesn't seem to inherit the value of a pointer set by the superclass' constructor.
Here's the code
//main.cpp
#include "Game/game.hpp"
#include "Game/Scene/start.hpp"
int main()
{
Game::Game *g = new Game::Game;
Game::Scene::Start *s = new Game::Scene::Start(g);
g->set_scene(s);
g->loop();
delete g;
return 0;
}
//Game/Scene/Scene.hpp
#ifndef GAME_SCENE_H
#define GAME_SCENE_H
namespace Game
{
class Game;
namespace Scene
{
class Scene
{
public:
Scene(Game *game);
virtual ~Scene();
virtual void handle_input() = 0;
virtual void update();
protected:
Game *game;
};
}
}
#endif
//Game/Scene/Scene.cpp
#include "scene.hpp"
#include <iostream>
Game::Scene::Scene::Scene(Game *game): game(game)
{
std::cout << "Game::Scene::Scene::Scene() > game: " << this->game << std::endl;
}
Game::Scene::Scene::~Scene() {}
void Game::Scene::Scene::update()
{
std::cout << "Game::Scene::Scene::update(): game: " << game << std::endl;
}
//Game/Scene/start.hpp
#ifndef GAME_SCENE_START_H
#define GAME_SCENE_START_H
#include "scene.hpp"
namespace Game
{
namespace Scene
{
class Start:
public Scene
{
public:
Start(Game *game);
void handle_input() override;
void update() override;
protected:
Game *game;
};
}
}
#endif
//Game/Scene/start.cpp
#include "start.hpp"
#include "../game.hpp"
#include <iostream>
Game::Scene::Start::Start(Game *game): Scene(game) {
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
void Game::Scene::Start::handle_input()
{}
void Game::Scene::Start::update()
{
Scene::update();
std::cout << "Game::Scene::Start::update(): game: " << game << std::endl;
game->set_keep_going(false);
}
//Game/game.hpp
#ifndef GAME_H
#define GAME_H
#include "Scene/scene.hpp"
namespace Game
{
class Game
{
public:
Game();
void loop();
void set_keep_going(bool state);
void set_scene(Scene::Scene *scene);
private:
bool keep_going;
Scene::Scene *current_scene;
};
}
#endif
//Game/game.cpp
#include "game.hpp"
#include <iostream>
Game::Game::Game():
keep_going(true),
current_scene(nullptr)
{}
void Game::Game::loop()
{
while(keep_going && current_scene)
{
current_scene->handle_input();
current_scene->update();
}
return;
}
void Game::Game::set_keep_going(bool state)
{
keep_going = state;
}
void Game::Game::set_scene(Scene::Scene *scene)
{
if(scene)
{
if(current_scene)
{
delete current_scene;
}
current_scene = scene;
}
}
And here is the output it generates:
Game::Scene::Scene::Scene() > game: 00000210FA38B330
Game::Scene::Start::Start() > game: 0000000000000000
Game::Scene::Scene::update(): game: 00000210FA38B330
Game::Scene::Start::update(): game: 0000000000000000
Segmentation fault
If I remove the 'this->' part that I used in the subclass constructor for debugging the output becomes this
Game::Scene::Scene::Scene() > game: 000001D247B5B370
Game::Scene::Start::Start() > game: 000001D247B5B370
Game::Scene::Scene::update(): game: 000001D247B5B370
Game::Scene::Start::update(): game: 0000000000000000
Segmentation fault
Which just makes it even weirder to me that it suddenly decided to reset itself.
It's without a doubt an incredibly simple thing that I'm overlooking, or some pointer shennanigans I've never run into before, but I'm stumped on what can possibly be going on here.
Any help or feedback om my code would be appriciated.
Upvotes: 0
Views: 273
Reputation: 19213
You have two members variables Scene::game
and Start::game
. You never set Start::game
. By default, game
resolves to Scene::game
and the base class's variable is shadowed. Turn on compiler warnings, maybe the compiler will warn about it, not sure in this particular case.
Fix:
Game::Scene::Start::Start(Game *game): Scene(game), game(game)
{
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
Or just delete Start::game
and use the member from Scene
. This probably what you have meant in the first place hence the protected
qualifier.
If you want feedback - do not use new
, use std::unique_ptr
instead. Even better, do not use ptrs at all this is not Java.
Upvotes: 1