2016-08-29 72 views
7

我试图挑起一个简单的状态模式,下面的一些优秀的教程这里经过:http://gameprogrammingpatterns.com/state.html状态模式C++

我通过这个电流教程半路上,我试图复制的静态实例每个状态,通过将它们包含在基类中。但是,当谈到切换状态时,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; 
} 

任何想法,为什么我的实现不是编制?

编辑:

所以响应早前辅导,对此我很感激,我修改了代码。我首先将它们全部放在单独的文件中,但这比测试代码量小的代价更麻烦。我简单地重写了一个声明类的头文件,然后在.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提供的答案确实会编译,但是我必须将“播放”和“引入”的实例移到类定义之外,然后我不能再将它们设置为静态的,我相信这很重要,因为我只需要每个实例的一个实例,我希望它们尽早初始化。

+0

您可能对我的[STTCL](https://github.com/makulik/sttcl)框架感兴趣。 –

回答

6

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

game.state_ = &GameState::play; 

行,他仍然不知道从GameStatePlaying继承。它只知道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) { 
} 

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

+0

好吧,这似乎很自信地回答我的问题!谢谢! –

3

之外的函数的实现外移到后面的所有类的定义中。

编译器必须完全看到继承类PlayingIntroduction,才能知道它们继承自GameState

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