尝试在 C++ 中实现状态管理器时出现链接错误

Getting a linking error while trying to implement a state manager in C++

本文关键字:链接 错误 管理器 状态 C++ 实现      更新时间:2023-10-16
这是我

在StackExchange上的第一个问题,所以如果需要更多信息,请告诉我。我会尽量做到完整和简洁。代码包含在下面。

我正在尝试实现此处找到的状态管理器:在C++中管理游戏状态

我已经下载了代码并几乎逐字复制了它(我更改了几个类和变量名称(。代码一直编译,直到我在 main.cpp 中添加以下行:

game.ChangeState(PlayState::Instance());

这会导致以下链接器错误:

错误 LNK2001:未解析的外部符号"私有:静态类 PlayState PlayState::m_Instance" (?m_Instance@PlayState@@0V1@A(

主.cpp

#include "JewelEngine.h"
#include "PlayState.h"
int main(int argc, const char* argv[])
{
    JewelEngine game;
    game.Init();
    game.ChangeState(PlayState::Instance());
    while(game.Running())
    {
        game.HandleEvents();
        game.Update();
        game.Render();
    }
    game.Cleanup();
    return 0;
}

PlayState.h

#ifndef PLAYSTATE_H
#define PLAYSTATE_H
#include "GameState.h"
class PlayState:public GameState
{
public:
    void Init();
    void Cleanup();
    void HandleEvents(JewelEngine* game);
    void Update(JewelEngine* game);
    void Render(JewelEngine* game);
    void Pause();
    void Resume();
    static PlayState* Instance()
    {
        return &m_Instance;
    }
protected:
    PlayState() { }
private:
    static PlayState m_Instance;
};
#endif

GameState.h

#ifndef GAMESTATE_H
#define GAMESTATE_H
#include "JewelEngine.h"
class GameState
{
public:
    virtual void Init() = 0;
    virtual void Cleanup() = 0;
    virtual void HandleEvents(JewelEngine* game) = 0;
    virtual void Update(JewelEngine* game) = 0;
    virtual void Render(JewelEngine* game) = 0;
    virtual void Pause() = 0;
    virtual void Resume() = 0;
    void ChangeState(JewelEngine* game, GameState* state)
    {
        game->ChangeState(state);
    }
protected:
    GameState();
};
#endif

我尝试删除静态成员和函数,使构造函数公开,而是在main中声明PlayState对象,然后将其地址传递到ChangeState函数中,但仍然会发生非常相似的链接错误。我已经无可救药地陷入这个问题 2 天了,非常感谢提供的任何帮助。谢谢。

您已经m_Instance声明了静态变量,但您需要定义它。

PlayState PlayState::m_Instance = PlayState(); // static variable definition follows the syntax:
                                               // (type) (var name) = (default assignment);

在 PlayState.cpp 文件中

从技术上讲,您不需要在此处调用 PlayState((,因为构造函数将自动调用。刚刚添加它以完成。关键是静态变量需要在其翻译单元中定义。类/结构中的声明是不够的,因为您需要"创建"它们。