gpt4 book ai didi

c++ - 状态模式 C++

转载 作者:可可西里 更新时间:2023-11-01 17:40:02 25 4
gpt4 key购买 nike

在学习了这里的一些优秀教程之后,我正在尝试创建一个简单的状态模式:http://gameprogrammingpatterns.com/state.html

我正在学习当前教程的一半,我正在尝试复制每个状态的静态实例,方法是将它们包含在基类中。但是,在切换状态时,g++ 会抛出此错误。

   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;
^

现在,我明白了错误涉及指针的转换,但我真的很想知道如何修复它。当我遵循这个人的代码时,我有点希望它能工作,但是因为他正在不断地改变它并试图加强最佳实践,所以我没有他的完整源代码可以遵循。但是,我觉得在我完成本教程的其余部分之前,在这个阶段理解代码对我来说很重要。

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

#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;
}

为什么我的实现没有编译有什么想法吗?

编辑:

所以为了响应之前的辅导,对此我非常感谢,我修改了代码。我首先将它们全部放在单独的文件中,但是对于这么少量的测试代码来说,这带来的麻烦超过了它的值(value)。我只是重写了一个声明类的头文件,然后在 .cpp 文件中定义了它们。

这是 .h 文件:

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 文件:

#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;
}

而且我仍然无法让它工作。之前的错误已经消失,但我正在努力访问“介绍”的静态实例并在基类内部播放。抛出的错误是:

/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 提供的答案确实可以编译,但是我必须将“播放”和“介绍”的实例移到类定义之外,然后我不能再将它们设置为静态的,我相信这很重要,因为我只需要每个实例的一个实例,我希望它们能尽早初始化。

最佳答案

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

的行
game.state_ = &GameState::play;

他仍然不知道Playing 继承自GameState。它只知道 Playing 是一个稍后声明的类。

您应该将类​​声明与方法实现分开。先声明所有类,再声明方法。在更大的项目中,您会将它们全部拆分为单独的 *.h 和 *.cpp 文件,并且这种排序会自然发生。

简化示例:

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) {
}

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

关于c++ - 状态模式 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39204985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com