C++ 状态机,继承 class,成员值语法不正确

C++ state machine, inherited class with member values with incorrect syntax

我不知道我的问题标题是否有意义,所以提前为此道歉。所以...我正在尝试为我尝试使用 C++ 和 SFML 制作的小游戏实现状态机。

我有一个 GameLoopObject 抽象 class,它需要一个 renderwindow 参数并且有这些虚拟方法:updatedrawhandleinputreset.

然后我有一个 GameState 抽象 class,它继承自 GameLoopObject,但没有添加任何新内容,所以它现在与 GameLoopObject 基本相同。

最后,我有一个 GameStateManager class 也继承自 GameLoopObject 并且应该处理我的游戏状态。

现在我的问题是我想在 GameStateManager 中使用 GameState currentStatenextState 成员变量,但我似乎找不到正确的 way/syntax 来声明这些并在之后使用它们。我宁愿将它们留空(如果在 C++ 中可能的话),因为 GameState object 在制作 GameStateManager object.[= 后立即存储在其中。 30=]

基本上,我想做的是这样的:

GameStateManager(sf::RenderWindow & w) : 
    GameLoopObject(w), 
    currentState(new GameState(w)), 
    nextState(new GameState(w));

这给了我一个 "no default constructor exists for class "GameLoopObject" "

这是我的其余代码:

/*
 * GameStateManager.hpp
 */

#ifndef GameStateManager_HPP
#define GameStateManager_HPP

#include "stdafx.h"
#include "GameLoopObject.hpp"
#include "GameState.hpp"
#include<string>
#include<map>

class GameStateManager : GameLoopObject {
private:
    GameState currentState;
    GameState nextState;
public:
    std::map<std::string, GameState> gameStates{}; // list where all known gamestates are stored.

    // methods
    GameStateManager(sf::RenderWindow & w);

    void AddGameState(std::string name, GameState * state);
    void SetNext(std::string name);
    void SwitchState();
    void HandleInput(); 
    void Update();
    void Draw();
    void Reset();
};

#endif //GameStateManager_HPP



/*
 * GameStateManager.cpp
 */
#include "stdafx.h"
#include "GameStateManager.hpp"

GameStateManager::GameStateManager(sf::RenderWindow & w)
// : GameLoopObject(w)
{
    GameState currentState(w);
    GameState nextState(w);
}

void GameStateManager::AddGameState(std::string name, GameState * state)
{
    gameStates.insert(std::make_pair(name, * state));
}

void GameStateManager::SetNext(std::string name)
{
    //check if user wants to exit (close window with X)
    if (gameStates.count(name))
    {
        nextState = gameStates[name];
    }
}

void GameStateManager::SwitchState()
{
    if (currentState != nextState)
    {
        currentState = nextState;
    }

}

void GameStateManager::HandleInput()
{
    // if(currentState != null)
    currentState.HandleInput();
}

void GameStateManager::Update()
{
    // if(currentState != null)
    currentState.Update();
}

void GameStateManager::Draw()
{
    // if(currentState != null)
    currentState.Draw();
}

void GameStateManager::Reset()
{
    // if(currentState != null)
    currentState.Reset();
}

我看到你这里有两个问题,都是因为你不能声明一个抽象的实例 class。 class 的成员应该是 GameState 指针。当您调用 new GameState 时,您也会面临同样的问题,这里没有可用的构造函数,因为 GameState 是抽象的。

我不确定您的 GameStateManager 是否是当前和下一个状态的所有者。在这种情况下,您应该将成员的类型更改为 std::unique_ptr<GameState>,否则只需使用 GameState*.

如果这些成员不拥有状态,您的构造函数不需要创建新的 GameState 对象来初始化这些成员,在这种情况下,您将传递一个指向现有 GameState 的指针。但是,如果他们这样做,您必须调用 new ConcreteGameState,其中 ConcreteGameStateGameState 的非抽象派生 class。

编辑: 查看您的成员函数,您几乎肯定想要一个原始指针。

编辑 2: 注意到您目前正在从 GameLoopObject 私有继承,您应该通过添加关键字将其更改为 public:

class GameStateManager: public GameLoopObject