简体   繁体   中英

Global Object interacted with by shared pointers

So, I've been trying to use a Shared pointer to a struct to hold all the data in my program that can be shared between states in my state machine.

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

typedef std::shared_ptr<GameData> GameDataRef;

this is one file that just provides an interface between shared data resources. called GameData.cpp

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

In my game.cpp file, if I understand this correctly, make_shared creates the object and assigns the shared_ptr named _data to it.

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

This is the line that creates a base state to start the game with. Never mind any part other than it takes the shared pointer as argument.

GameDataRef _data;

I make another shared pointer in the State_Splash.cpp called _data

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

In the constructor, I (forgot the term for what comes after the : here)

std::cout << _data->x;

this prints out 0 to the console, even though x is defined in the struct as 1. I ran this test because a texture I loaded into _data->assets in the Game.cpp was out of scope(blank white screen) when I tried to reference it to a sprite in the State_Splash.cpp.

My question is, am I doing something wrong with shared pointers? Or is there a better way to make some shared resource depot for the entire program?

Or is there a better way to make some shared resource depot for the entire program?

Singletons have bad reputation. A lot of it comes from pre-C++11 era when it was hard to get them right. C++11 makes them safe. It's also a global object - so it's subject to all considerations regarding globals. They should be avoided except when they make your program better.

Singletons work pretty well in game applications. I'd just create something like GameContext singleton and forget about shared pointers. Your game data is global by design.

However if your code is designed to have multiple such objects, then singleton won't work for you.

A singleton or global of any kind trashes composition and testability. There is almost never a good reason for such things.

Better to use dependency injection. Then you can test the components of your game with only a model of the dependency.

#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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM