首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >状态模式C++

状态模式C++
EN

Stack Overflow用户
提问于 2016-08-29 11:18:33
回答 2查看 1.6K关注 0票数 8

我正在尝试引入一个简单的状态模式,在下面介绍了一些优秀的教程之后:http://gameprogrammingpatterns.com/state.html

在本教程中,我已经完成了一半,我试图通过将它们包含在基类中来复制每个状态的静态实例。然而,当涉及到切换状态时,g++抛出了这个错误。

代码语言:javascript
复制
   state_test.cpp: In member function ‘virtual void Introduction::handleinput(Game&, int)’:
state_test.cpp:55:16: error: cannot convert ‘Playing*’ to ‘GameState*’ in assignment
    game.state_ = &GameState::play;
                ^

现在,我理解了这个错误涉及指针的转换,但是我真的很难知道如何修复它。当我遵循这些家伙的代码时,我有点希望它能起作用,但是因为他正在改变它,并试图加强最佳实践,所以我没有他完整的源代码可以遵循。但是,我觉得在本教程的其余部分开始之前,在这个阶段理解代码是很重要的。

下面是我创建的代码,试图复制他的状态系统:

代码语言:javascript
复制
#include <iostream>

class Game;
class Introduction;
class Playing;

class GameState
{
public:

    static Introduction intro;
    static Playing play;

    virtual ~GameState() {std::cout << "an undefined GameState has been destroyed" << std::endl;}
    virtual void handleinput(Game& game, int arbitary) {}
    virtual void update(Game& game) {}

};

class Game
{
public:

    Game()
    {}
    ~Game()
    {}

    virtual void handleinput(int arbitary)
        {
            state_->handleinput(*this, arbitary);
        }

    virtual void update()
        {
            state_->update(*this);
        }

//private: 
    GameState* state_;
};

class Introduction : public GameState
{
public:

    Introduction()  
    {
        std::cout << "constructed Introduction state" << std::endl;
    }

    virtual void handleinput(Game& game, int arbitary) 
        {
            if (arbitary == 1)
            game.state_ = &GameState::play;
        }

    virtual void update(Game& game) {}
};

class Playing : public GameState
{
public:
    Playing()   {std::cout << "constructed Playing state" << std::endl;}

    virtual void handleinput(Game& game, int arbitary) 
        {
            if (arbitary == 0)
            game.state_ = &GameState::intro;
        }

    virtual void update(Game& game) {}
};

int main(int argc, char const *argv[])
{
    Game thisgame;

    return 0;
}

知道为什么我的实现没有编译吗?

编辑:

因此,为了回应先前的辅导,我对此非常感激,我修改了代码。首先,我把所有这些放在单独的文件中,但这比这么少量的测试代码更麻烦。我只需重写一个声明类的头文件,然后在.cpp文件中定义它们。

下面是.h文件:

代码语言:javascript
复制
class Introduction;
class Playing;
class Game;
class GameState;

class GameState
{
    public:

    static Introduction intro;
    static Playing play;

    virtual ~GameState();
    virtual void handleinput(Game& game, int arbitary);
    virtual void update(Game& game);

};


class Introduction : public GameState
{
public:

    Introduction();

    virtual void handleinput(Game& game, int arbitary); 

    virtual void update(Game& game);

};

class Playing : public GameState
{
public:
    Playing();

    virtual void handleinput(Game& game, int arbitary);

    virtual void update(Game& game);    
};


class Game
{
public:

    Game();

    ~Game();

    virtual void handleinput(int arbitary);

    virtual void update();

    GameState* state_;

};

下面是.cpp文件:

代码语言:javascript
复制
#include <iostream>
#include "state.h"


GameState::~GameState() 
    {std::cout << "Exiting Game State Instance" << std::endl;}
void GameState::handleinput(Game& game, int arbitary) 
    {}
void GameState::update(Game& game) 
    {}



Game::Game()
    {}
Game::~Game()
    {}
void Game::handleinput(int arbitary)
        {
            state_->handleinput(*this, arbitary);
        }

void Game::update()
        {
            state_->update(*this);
        }


Introduction::Introduction()    
    {
        std::cout << "constructed Introduction state" << std::endl;
    }

void Introduction::handleinput(Game& game, int arbitary) 
        {
            if (arbitary == 1)
            game.state_ = &GameState::play;
        }

void Introduction::update(Game& game) {}


Playing::Playing()  
        {
            std::cout << "constructed Playing state" << std::endl;
        }

void Playing::handleinput(Game& game, int arbitary) 
        {
            if (arbitary == 0)
            game.state_ = &GameState::intro;
        }

void Playing::update(Game& game) {}



int main(int argc, char const *argv[])
{
    Game mygame;
    return 0;
}

但我还是不能让它起作用。前面的错误已经消失了,但是我很难访问"introduction“的静态实例,并在基类中运行。引发的错误是:

代码语言:javascript
复制
/tmp/ccH87ioX.o: In function `Introduction::handleinput(Game&, int)':
state_test.cpp:(.text+0x1a9): undefined reference to `GameState::play'
/tmp/ccH87ioX.o: In function `Playing::handleinput(Game&, int)':
state_test.cpp:(.text+0x23f): undefined reference to `GameState::intro'
collect2: error: ld returned 1 exit status

我以为我被调查过了!太沮丧了!

我要补充的是,RustyX提供的答案确实是编译的,但是我必须将“that”和"introduction“的实例移到类定义之外,然后我不能再将它们设置为静态的,我认为这很重要,因为我只需要每个实例的一个实例,我希望尽早初始化它们。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-29 11:25:06

问题是编译器从上到下读取文件。在包含

代码语言:javascript
复制
game.state_ = &GameState::play;

他仍然不知道Playing是从GameState继承来的。它只知道Playing是以后将声明的类。

您应该将类声明与方法实现分开。先拥有所有的类声明,然后才有方法实现。在更大的项目中,您会将它们分割到单独的*.h和*.cpp文件中,这种排序将自然发生。

缩短的例子:

代码语言:javascript
复制
class Playing : public GameState
{
public:
    Playing();

    virtual void handleinput(Game& game, int arbitary);

    virtual void update(Game& game);
};

// Declarations of other classes...


Playing::Playing() {
    std::cout << "constructed Playing state" << std::endl;
}

void Playing::handleinput(Game& game, int arbitrary) {
    if (arbitary == 0)
        game.state_ = &GameState::intro;
    }
}

void Playing::update(Game& game) {
}

您可以在类声明中保留一些方法。通常情况下,如果方法很小,会从内联中受益,并且不存在这种循环依赖问题,就会这样做。

票数 7
EN

Stack Overflow用户

发布于 2016-08-29 11:26:59

将函数的实现移到所有类的定义之后。

编译器必须完整地查看继承的类PlayingIntroduction,才能知道它们是从GameState继承的。

代码语言:javascript
复制
#include <iostream>

class Game;
class Introduction;
class Playing;

class GameState
{
public:

    static Introduction intro;
    static Playing play;

    virtual ~GameState() {std::cout << "an undefined GameState has been destroyed" << std::endl;}
    virtual void handleinput(Game& game, int arbitary) {}
    virtual void update(Game& game) {}

};

class Game
{
public:

    Game()
    {}
    ~Game()
    {}

    virtual void handleinput(int arbitary)
        {
            state_->handleinput(*this, arbitary);
        }

    virtual void update()
        {
            state_->update(*this);
        }

//private: 
    GameState* state_;
};

class Introduction : public GameState
{
public:

    Introduction()  
    {
        std::cout << "constructed Introduction state" << std::endl;
    }

    virtual void handleinput(Game& game, int arbitary);

    virtual void update(Game& game) {}
};

class Playing : public GameState
{
public:
    Playing()   {std::cout << "constructed Playing state" << std::endl;}

    virtual void handleinput(Game& game, int arbitary);

    virtual void update(Game& game) {}
};

void Introduction::handleinput(Game& game, int arbitary) 
{
    if (arbitary == 1)
        game.state_ = &GameState::play;
}

void Playing::handleinput(Game& game, int arbitary) 
{
    if (arbitary == 0)
        game.state_ = &GameState::intro;
}

Introduction GameState::intro;
Playing GameState::play;


int main(int argc, char const *argv[])
{
    Game thisgame;

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

https://stackoverflow.com/questions/39204985

复制
相关文章

相似问题

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