首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >超类成员指针在被子类访问时变为null

问超类成员指针在被子类访问时变为null
EN

Stack Overflow用户
提问于 2020-12-15 02:51:06
回答 1查看 52关注 0票数 0

我最近读了很多东西,决定尝试实现一个简单的State模式,看看事情是如何组合在一起的。

然而,我遇到了一个我以前从未遇到过的问题:场景的子类(Start)似乎没有继承超类的构造函数设置的指针的值。

下面是代码

代码语言:javascript
复制
//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;
}
代码语言:javascript
复制
//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
代码语言:javascript
复制
//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;
}
代码语言:javascript
复制
//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
代码语言:javascript
复制
//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);
}
代码语言:javascript
复制
//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
代码语言:javascript
复制
//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;
    }
}

下面是它生成的输出:

代码语言:javascript
复制
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 ->‘部分,则输出结果如下所示

代码语言:javascript
复制
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

这让我觉得更奇怪的是它突然决定重置自己。

毫无疑问,这是我忽略的一件非常简单的事情,或者是一些我以前从未遇到过的指针骗局,但我对这里可能发生的事情感到困惑。

对我的代码的任何帮助或反馈都会得到重视。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-15 03:05:40

您有两个成员变量Scene::game和Start::game。您从未设置过Start::game。默认情况下,game解析为Scene::game,基类的变量被屏蔽。打开编译器警告,也许编译器会对此发出警告,但在这种情况下不能确定。

修复:

代码语言:javascript
复制
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。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65294775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档