【问题标题】:Using a static variable in an abstract base class在抽象基类中使用静态变量
【发布时间】:2015-12-07 14:24:25
【问题描述】:

我正在尝试创建一个状态机。我创建了一个名为BaseState 的类,所有状态都从该类继承。我遇到的问题是,当子类更改 BaseState 成员变量时,它不会更改所有继承类的变量。根据我对编程的了解,这是我使用静态的时候。但在我的情况下,我收到了链接器错误 (LNK2001)。

所以当我在SplashState 中调用ChangeState(State::MenuState); 时,它会切换,但会切换回来,因为BaseState 中的值没有改变。

class StateMachine
{
private:
    State                   _currentState;
    std::vector<BaseState*> _baseStates;
    void ProcessStateRequest();

public:
    StateMachine(InitVar initVar);
    ~StateMachine();

    void Update(float deltaTime);
};

添加这样的状态:

StateMachine::StateMachine(InitVar initVar)
{
    _currentState = State::SPLASHSTATE;

    for (int i = 0; i < State::EXITSTATE; i++)
    {
        switch (i)
        {
        case SPLASHSTATE:
        {
            _baseStates.push_back(new SplashState(initVar));
            break;
        }
        case MENUSTATE:
        {
            _baseStates.push_back(new MenuState(initVar));
            break;
        }
        case PLAYSTATE:
        {
            _baseStates.push_back(new PlayState(initVar));
            break;
        }
        case OPTIONSSTATE:
        {
            _baseStates.push_back(new OptionsState(initVar));
            break;
        }
        }
    }
}

像这样改变状态:

void StateMachine::ProcessStateRequest()
{
    //if currentState does not match with the new requested state.
    if (_currentState != _baseStates[_currentState]->GetNewStateRequest())
    {
        _baseStates[_currentState]->OnStateExit();
        _currentState = _baseStates[_currentState]->GetNewStateRequest();
        _baseStates[_currentState]->OnStateEnter();
    }
}

内部basestate.h

enum State
{
    SPLASHSTATE,
    MENUSTATE,
    PLAYSTATE,
    OPTIONSSTATE,
    EXITSTATE,
};

class BaseState
{
private:
    State               _newStateRequest; //Cannot edit this from subclasses. Adding static causes linker error.
protected:
    ObjectHandler*      _objectHandler;
    UIHandler*          _uiHandler;

    void ChangeState(State newState);
public:
    BaseState(InitVar initVar);
    ~BaseState();

    virtual void Update(float deltaTime) = 0;
    virtual void OnStateEnter() = 0;
    virtual void OnStateExit() = 0;

    State GetNewStateRequest()const;
};

basestate.cpp的最后一部分:

BaseState::BaseState(InitVar initVar)
{
    _objectHandler      = initVar.objectHandler;
    _uiHandler          = initVar.uiHandler;
    _newStateRequest    = SPLASHSTATE;
}

BaseState::~BaseState()
{}

void BaseState::ChangeState(State newState)
{
    _newStateRequest = newState;
}

State BaseState::GetNewStateRequest() const
{
    return _newStateRequest;
}

【问题讨论】:

  • 你确定你在basestate.cpp中定义了你的静态变量,比如State BaseState::_newStateRequest;吗?
  • 你问的是如何定义静态变量work,还是ChangeState的问题?请一题一题。哦,如果是关于第一个(你的标题是关于)的,那么it's a duplicate of this
  • MikeCat,解决了这个问题。我不知道我必须这样做。
  • 避免使用静态变量。为什么你认为你需要一个?您是否绝对确定在整个程序中只需要一个线程不安全状态机?如果您需要每台机器一个新的状态请求,请将_newStateRequest 设为StateMachine 的成员,而不是BaseState 的成员。静态变量不是解决方案,而是一种逃避。

标签: c++ inheritance static state-machine


【解决方案1】:

cmets 中的 MikeCAT 给出了这个答案。这样做解决了问题;

class BaseState
{
private:
    static State BaseState::_newStateRequest;
    //State             _newStateRequest;

#include "BaseState.h"

State BaseState::_newStateRequest;

BaseState::BaseState(InitVar initVar)

【讨论】:

    猜你喜欢
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 2011-07-27
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多