当被子类访问时超类成员指针变为空
Superclass member pointer becomes null when accessed by subclass
我最近看了很多书,决定尝试实现一个简单的状态模式,看看它们是如何组合在一起的。
但是,我 运行 遇到了一个以前从未遇到过的问题:场景的子类 (Start) 似乎没有继承超类构造函数设置的指针值。
这是代码
//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;
}
}
这是它生成的输出:
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
如果我删除我在子类构造函数中用于调试的 '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
这让我觉得更奇怪的是它突然决定自行重置。
毫无疑问,我忽略了一个非常简单的事情,或者一些我以前从未 运行 接触过的指针恶作剧,但我对这里可能发生的事情感到困惑。
任何关于我的代码的帮助或反馈都将不胜感激。
您有两个成员变量 Scene::game
和 Start::game
。你永远不会设置 Start::game
。默认情况下,game
解析为 Scene::game
并且基础 class 的变量被隐藏。打开编译器警告,也许编译器会警告它,在这种特殊情况下不确定。
修复:
Game::Scene::Start::Start(Game *game): Scene(game), game(game)
{
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
或者只删除 Start::game
并使用 Scene
中的成员。这可能是您最初的意思,因此 protected
限定词。
如果您需要反馈 - 不要使用 new
,请改用 std::unique_ptr
。更好的是,根本不要使用 ptrs 这不是 Java.
我最近看了很多书,决定尝试实现一个简单的状态模式,看看它们是如何组合在一起的。
但是,我 运行 遇到了一个以前从未遇到过的问题:场景的子类 (Start) 似乎没有继承超类构造函数设置的指针值。
这是代码
//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;
}
}
这是它生成的输出:
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
如果我删除我在子类构造函数中用于调试的 '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
这让我觉得更奇怪的是它突然决定自行重置。
毫无疑问,我忽略了一个非常简单的事情,或者一些我以前从未 运行 接触过的指针恶作剧,但我对这里可能发生的事情感到困惑。
任何关于我的代码的帮助或反馈都将不胜感激。
您有两个成员变量 Scene::game
和 Start::game
。你永远不会设置 Start::game
。默认情况下,game
解析为 Scene::game
并且基础 class 的变量被隐藏。打开编译器警告,也许编译器会警告它,在这种特殊情况下不确定。
修复:
Game::Scene::Start::Start(Game *game): Scene(game), game(game)
{
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
或者只删除 Start::game
并使用 Scene
中的成员。这可能是您最初的意思,因此 protected
限定词。
如果您需要反馈 - 不要使用 new
,请改用 std::unique_ptr
。更好的是,根本不要使用 ptrs 这不是 Java.