简体   繁体   English

这是多态性吗?这是不好的做法吗?

[英]Is this Polymorphism and is this bad practice?

I'm setting up a State system for my game.我正在为我的游戏设置一个 State 系统。

class State
{
protected:
 enum State_
 {
     STATE_INTRO,
     STATE_GAME,
     STATE_PAUSE,
     STATE_CUTSCENE,
 };
public:
 State();
 virtual void run(State_) = 0;
 virtual ~State(); // virtual destructor cus we will be inheriting this class
};

I then have inherited classes which represent each state然后我继承了代表每个 state 的类

class IntroState : public State
{

public:
    void run(State_ STATE);
};

I want the run function to have different functionality based off of what state the game is in, is it bad practice to achieve that like this:我希望run function 根据游戏所在的 state 具有不同的功能,这样实现是不是不好的做法:

void IntroState::run(State_ STATE)
{
    if (STATE == STATE_INTRO)
    {
        // load the intro
    }
}

I'm not sure how else to do this, thanks (and keep in my mind I'm JUST learning about states so I might be completely off here)我不确定该怎么做,谢谢(请记住,我只是在学习状态,所以我可能会完全离开这里)

I think you don't need polymorphism in your case since you will only have one State class in your application (correct me if I'm wrong).我认为您的情况不需要多态性,因为您的应用程序中只有一个State class(如果我错了请纠正我)。

You're run function would look like this:你运行 function 看起来像这样:

void run(State_ state)
{
  switch (state)
  {
    case STATE_INTRO:
      doIntro();
    case STATE_BLAH:
      doBlah();
    // fill all you states...
  }
}

void doIntro()
{
  // do something for the intro
}

void doBlah()
{
  // do something for blah
}

Now if you really wanna get fancy and remove the switch statement:现在,如果你真的想变得有趣并删除switch语句:

class State
{
    private:
        void doA() {}
        void doB() {}

        enum State_
        {
            A = 0,
            B,
            END_
        };

        std::function<void(void)> functions[END_];

    public:
        State()
        {
            functions[A] = std::bind(&State::doA, this);
            functions[B] = std::bind(&State::doB, this);
        }

        void run(State_ state)
        {
            functions[state]();
        }
};

To expand on my comment, here is a possible approach (improvements are appreciated):为了扩展我的评论,这是一种可能的方法(感谢改进):

class Game {
  //... Initialize all State-derived classes in constructor and put them in states (not shown)
  vector<unique_ptr>> states;
  State_ currentState {STATE_INTRO};
  State_ nextState {STATE_INTRO};
  public:
    void setNextState(State_ state ) {nextState = state;}
    void Play() { 
      for(;;) { //endless loop
        if (!states[currentState]->run()) return;//stopping when run returns false
        currentState = nextState;
      }
    }
};

And run could look like this: run看起来像这样:

class IntroState : public State {
  //... 
  void run(Game& game) {
    // do stuff
    game.setNextState(STATE_GAME);
    return true;
  }
};

Of course, you need to figure out the include order, and you'll need to forward-declare Game in State.hpp (the code shown here only shows the central idea).当然,你需要弄清楚include顺序,你需要在State.hpp中转发声明Game (这里的代码只是展示了中心思想)。 Also, the implementations of run and Play should of course be in seperate.cpp files (didn't do that here so this example wouldn't get too long)此外, runPlay的实现当然应该放在单独的.cpp 文件中(这里没有这样做,所以这个例子不会太长)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM