【问题标题】:Global Object interacted with by shared pointers通过共享指针与之交互的全局对象
【发布时间】:2018-01-13 03:05:05
【问题描述】:

因此,我一直在尝试使用指向结构的 Shared 指针来保存程序中可以在状态机中的状态之间共享的所有数据。

struct GameData
{
    StateMachine machine;
    sf::RenderWindow window;
    AssetManager assets;
    InputManger input;
    const int x = 1;
};

typedef std::shared_ptr<GameData> GameDataRef;

这是一个仅在共享数据资源之间提供接口的文件。称为 GameData.cpp

GameDataRef _data = std::make_shared<GameData>();

在我的 game.cpp 文件中,如果我理解正确,make_shared 会创建对象并将名为 _data 的 shared_ptr 分配给它。

StateRef _splash = std::make_unique<State_Splash>(_data);

这是创建游戏开始时使用的基本状态的行。除了将共享指针作为参数之外,别管其他任何部分。

GameDataRef _data;

我在 State_Splash.cpp 中创建了另一个名为 _data 的共享指针

State_Splash::State_Splash(GameDataRef GDR) : _data(GDR)

在构造函数中,我(忘记了 : 之后的术语)

std::cout << _data->x;

这会将 0 打印到控制台,即使 x 在结构中定义为 1。我运行此测试是因为我加载到 Game.cpp 中的 _data->assets 的纹理超出范围(空白屏幕)当我尝试将它引用到 State_Splash.cpp 中的精灵时。

我的问题是,我在共享指针方面做错了吗?或者有没有更好的方法为整个程序制作一些共享资源库?

【问题讨论】:

  • 试试cout &lt;&lt; _data.get()。它显示了什么?
  • 返回 00221E40
  • 您提供的行看起来不错。一定有一些你没有注意到或认为不重要的东西。尝试将示例减少到最小,看看它是否重现。理想情况下,所有代码都应该在一个 cpp 文件中。然后您可以轻松地将其粘贴到此处。
  • #include #include using namespace std;结构游戏数据 { 常量 int x = 1; }; typedef std::shared_ptr GameDataRef; int main() { GameDataRef _data = std::make_shared(); coutx; }
  • 尽我所能,我无法重现您的问题。您确定特定的std::cout 插入是将0 转储到控制台吗?一个相当少的代码集(不会复制,所以它可能不值多少钱)can be found here

标签: c++ constructor arguments shared-ptr sfml


【解决方案1】:

任何类型的单例或全局都会破坏组合和可测试性。这样的事情几乎没有充分的理由。

最好使用依赖注入。然后你可以只用一个依赖模型来测试你游戏的组件。

#include <vector>

struct StateMachine{};
namespace sf { struct RenderWindow {}; }
struct AssetManager {};
struct InputManager {};

struct GameData
{
    StateMachine machine;
    sf::RenderWindow window;
    AssetManager assets;
    InputManager input;
    const int x = 1;
};

struct action {};
std::vector<action> checkInputs(InputManager&);

void runGame(GameData& gameData)
{
    while (1) {
        auto inputActions = checkInputs(gameData.input);
    }

}

int main()
{
    GameData gameData;

    runGame(gameData);
}

【讨论】:

    【解决方案2】:

    或者有没有更好的方法来为整个程序制作一些共享资源库?

    单身人士名声不好。其中很多来自 C++11 之前的时代,当时很难把它们弄好。 C++11 使它们安全。它也是一个全局对象——因此它受制于有关全局变量的所有考虑。除非它们使您的程序更好,否则应避免使用它们。

    单例在游戏应用程序中运行良好。我只会创建类似 GameContext 单例的东西,而忘记共享指针。您的游戏数据在设计上是全球性的。

    但是,如果您的代码设计为具有多个此类对象,那么单例将不适合您。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多