2017-08-05 3 views
0

Also habe ich versucht, einen Shared-Zeiger auf eine Struktur zu verwenden, um alle Daten in meinem Programm zu halten, die zwischen Zuständen in meinem Zustandsautomaten geteilt werden können.Globales Objekt interagierte mit freigegebenen Zeigern

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

typedef std::shared_ptr<GameData> GameDataRef; 

Dies ist eine Datei, die nur eine Schnittstelle zwischen freigegebenen Datenressourcen bereitstellt. GameData.cpp

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

In meiner game.cpp Datei mit dem Namen, wenn ich das richtig verstehen, make_shared das Objekt erstellt und weist den shared_ptr namens _data zu.

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

Dies ist die Zeile, die einen Basiszustand erstellt, um das Spiel mit zu starten. Abgesehen von der Tatsache, dass der Shared-Pointer als Argument verwendet wird.

GameDataRef _data; 

ich einen anderen gemeinsamen Zeiger im State_Splash.cpp machen _DATA

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

im Konstruktor I (vergessen, den Begriff für das, was nach dem kommt: hier)

std::cout << _data->x; 

Dies gibt 0 an die Konsole aus, obwohl x in der Struktur als 1 definiert ist. Ich habe diesen Test ausgeführt, weil eine Textur, die ich in _data-> Assets in der Game.cpp geladen habe, außerhalb des Gültigkeitsbereichs (leerer weißer Bildschirm) war zu referenc e es zu einem Sprite in der State_Splash.cpp.

Meine Frage ist, mache ich etwas falsch mit geteilten Zeigern? Oder gibt es eine bessere Möglichkeit, ein gemeinsames Ressourcen-Depot für das gesamte Programm zu erstellen?

+0

Versuchen Sie 'cout << _data.get()'. Was zeigt es? –

+0

es gibt zurück 00221E40 –

+1

Die Linien, die Sie zur Verfügung gestellt haben, sehen gut aus. Es muss etwas geben, das du nicht merkst oder nicht für wichtig hältst. Versuchen Sie, das Beispiel auf ein Minimum zu reduzieren und zu überprüfen, ob es sich reproduziert.Idealerweise sollte sich der gesamte Code in einer cpp-Datei befinden. Dann können Sie ihn hier einfach einfügen. – Sergei

Antwort

0

Oder gibt es einen besseren Weg, um etwas gemeinsam genutzte Ressource Depot für das gesamte Programm zu machen?

Singletons haben einen schlechten Ruf. Vieles davon stammt aus der Zeit vor C++ 11, als es schwierig war, sie richtig zu machen. C++ 11 macht sie sicher. Es ist auch ein globales Objekt - daher unterliegt es allen Überlegungen bezüglich Globals. Sie sollten vermieden werden, außer wenn sie Ihr Programm verbessern.

Singletons funktionieren in Spielanwendungen ziemlich gut. Ich würde einfach etwas wie GameContext Singleton erstellen und die geteilten Zeiger vergessen. Ihre Spieldaten sind global angelegt.

Wenn Ihr Code jedoch mehrere solcher Objekte enthalten soll, funktioniert Singleton nicht für Sie.

0

Ein Singleton oder global jeder Art verschrottet Zusammensetzung und Testbarkeit. Für solche Dinge gibt es fast nie einen guten Grund.

Bessere Abhängigkeitsinjektion. Dann können Sie die Komponenten Ihres Spiels nur mit einem Modell der Abhängigkeit testen.

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