C++ 状态机,继承 class,成员值语法不正确
C++ state machine, inherited class with member values with incorrect syntax
我不知道我的问题标题是否有意义,所以提前为此道歉。所以...我正在尝试为我尝试使用 C++ 和 SFML 制作的小游戏实现状态机。
我有一个 GameLoopObject
抽象 class,它需要一个 renderwindow
参数并且有这些虚拟方法:update
、draw
、handleinput
和 reset
.
然后我有一个 GameState
抽象 class,它继承自 GameLoopObject
,但没有添加任何新内容,所以它现在与 GameLoopObject
基本相同。
最后,我有一个 GameStateManager
class 也继承自 GameLoopObject
并且应该处理我的游戏状态。
现在我的问题是我想在 GameStateManager
中使用 GameState
currentState
和 nextState
成员变量,但我似乎找不到正确的 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
,其中 ConcreteGameState
是 GameState
的非抽象派生 class。
编辑:
查看您的成员函数,您几乎肯定想要一个原始指针。
编辑 2:
注意到您目前正在从 GameLoopObject
私有继承,您应该通过添加关键字将其更改为 public:
class GameStateManager: public GameLoopObject
我不知道我的问题标题是否有意义,所以提前为此道歉。所以...我正在尝试为我尝试使用 C++ 和 SFML 制作的小游戏实现状态机。
我有一个 GameLoopObject
抽象 class,它需要一个 renderwindow
参数并且有这些虚拟方法:update
、draw
、handleinput
和 reset
.
然后我有一个 GameState
抽象 class,它继承自 GameLoopObject
,但没有添加任何新内容,所以它现在与 GameLoopObject
基本相同。
最后,我有一个 GameStateManager
class 也继承自 GameLoopObject
并且应该处理我的游戏状态。
现在我的问题是我想在 GameStateManager
中使用 GameState
currentState
和 nextState
成员变量,但我似乎找不到正确的 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
,其中 ConcreteGameState
是 GameState
的非抽象派生 class。
编辑: 查看您的成员函数,您几乎肯定想要一个原始指针。
编辑 2:
注意到您目前正在从 GameLoopObject
私有继承,您应该通过添加关键字将其更改为 public:
class GameStateManager: public GameLoopObject