wie am besten Einstellungen oder größere Datenmengen verwalten?



  • Hallo Leute,

    Gibt es eine empfohlene Struktur, um viele gruppierte Daten zu verwalten?
    Ich habe beispielsweise eine klassische Konfigurationsdatei (.ini), die ich beim Programmstart einlese:

    [Gruppe1]
    Key_1 = Value_1
    Key_2 = Value_2
    Key_3 = Value_3
    
    [Gruppe2]
    Key_A = Value_A
    Key_B = Value_B
    Key_C = Value_C
    
    [Gruppe3]
    Key_X = Value_X
    Key_Y = Value_Y
    Key_Z = Value_Z
    
    [...und viele mehr...]
    

    Wie verwalte ich diese Daten am besten?

    1. Möglichkeit: Ich verwende Klassen mit eingebetteten Objekten:

    class Gruppe1
    {
    public:
    	Gruppe1(){};
    	~Gruppe1(){};
    
    	int getKey1() const
    	{
    		return m_key_1;
    	}
    
    	void setKey1(int value)
    	{
    		this->m_key_1 = value;
    	}
    	[...]
    
    private:
    	int m_key_1;
    	int m_key_2;
    	int m_key_3;
    };
    
    class MeineDaten
    {
    public:
    	MeineDaten(){};
    	~MeineDaten(){};
    
    	Gruppe1 getGruppe1() const;
    	void setGruppe1(Gruppe1 const &gruppe1);
    	[...]
    
    private:
    	Gruppe1 m_gruppe1;
    	Gruppe2 m_gruppe2;
    	Gruppe3 m_gruppe3;
    };
    
    void main()
    {
    	MeineDaten settings;
    
    	// eine Info abrufen
    	Gruppe1 gruppe1 = settings.getGruppe1();
    	int meinWert = gruppe1.getKey1();
    
    	// daten hineinschreiben
    	gruppe1.setKey1(123);
    	settings.setGruppe1(gruppe1);
    }
    

    Das die Namensgebung nicht optimal ist und die Variablen hier nicht initialisiert werden, ist mir bewusst.
    Diese Methode kommt mir sehr unübersichtlich und umständlich vor.

    2. Möglichkeit: Verwendung von einzelnen Strukturen ohne getter und setter

    struct Gruppe1
    {
    	int key_1;
    	int key_2;
    	int key_3;
    };
    
    [...]
    
    struct MeineDaten
    {
    	Gruppe1 gruppe1;
    	Gruppe2 gruppe2;
    	Gruppe3 gruppe3;
    };
    
    void main()
    {
    	MeineDaten settings;
    
    	// eine Info abrufen
    	int meinWert = settings.gruppe1.key_1;
    
    	// daten hineinschreiben
    	settings.gruppe1.key_1 = 123;
    }
    

    3. Möglichkeit: Definition einer einzigen Struktur ohne getter und setter

    struct MeineDaten
    {
    	struct
    	{
    		int key_1;
    		int key_2;
    		int key_3;
    	}gruppe1;
    
    	struct
    	{
    		int key_A;
    		int key_B;
    		int key_C;
    	}gruppe2;
    
    	struct
    	{
    		int key_X;
    		int key_Y;
    		int key_Z;
    	}gruppe3;
    };
    
    void main()
    {
    	MeineDaten settings;
    
    	// eine Info abrufen
    	int meinWert = settings.gruppe1.key_1;
    
    	// daten hineinschreiben
    	settings.gruppe1.key_1 = 123;
    }
    

    Das geht definitiv am schnellsten, aber ist es auch ok so? Gibt es Ansätze die gundsätzlich besser dafür geeignet sind? Mir ist zumindest nichts anderes bekannt (nur sowas wie XML parser & co.).
    Habt ihr Tipps für mich?

    viele Grüße,
    SBond



  • Boost.PropertyTree



  • wahrscheinlich komme ich um boost nicht herum, so oft wie ich darauf stoplere.

    Ich schau mir das mal an 🙂



  • Boost.PropertyTree ist ein generisches DOM-Format für Settings.

    Und ich bin kein Fan davon Settings primär über ein generisches DOM-Format anzusprechen. Als Hilfe beim Einlesen bzw. Schreiben ist das OK, aber dort wo die Settings verwendet werden, sollten sie nicht in sowas stecken.

    Die wichtigsten Gründe dagegen sind für mich:

    1. Ich will keine unnötige Dependency auf das DOM-Format im Interface
    2. Generisches DOM-Format heisst normalerweise Zugriff auf die Werte per Name (String-Key), und das ist unübersichtlich, fehleranfällig und nicht refactoringfreundlich


  • Danke für die Info 🙂

    Ich habe es erstmal nach 'Möglichkeit 3' gelöst, da ich mich noch etwas gegen Boost wehre (ich versuche es lieber erstmal selber zu lösen, als Libs einzubinden).

    Hier ein Beispiel für die .ini aus meinem ersten Post:

    struct MeineDaten
    {
    	MeineDaten:gruppe1(), gruppe2(), gruppe3() {}
    
        struct gruppe1
        {
    		gruppe1():key_1(0), key_2(0), key_3(0) {}
            int key_1;
            int key_2;
            int key_3;
        }gruppe1;
    
        struct gruppe2
        {
    		gruppe1():key_A(0), key_B(0), key_C(0) {}
            int key_A;
            int key_B;
            int key_C;
        }gruppe2;
    
        struct gruppe3
        {
    		gruppe1():key_X(0), key_Y(0), key_Z(0) {}
            int key_X;
            int key_Y;
            int key_Z;
        }gruppe3;
    };
    
    void main()
    {
        MeineDaten settings;
    
        // eine Info abrufen
        int meinWert = settings.gruppe1.key_1;
    
        // daten hineinschreiben
        settings.gruppe1.key_1 = 123;
    }
    

    Initialisierungslisten in structs sehen für mich noch etwas gewöhnungsbedürftig aus. Da ich aber auch std::string verwende, kann ich die Initialisierung nicht mit memset() machen. Für einfache ini-Dateien, sollte die Lösung ok sein.



  • Wie wäre es mit Serialisierung? Hier ist eine Header-only Bibliothek http://uscilab.github.io/cereal/index.html

    Ein kleines Beispiel:

    #include <cereal/archives/xml.hpp>
    #include <iostream>
    
    struct Foo
    {
        Foo(int a, int b)
            : a(a), b(b)
        {
        }
    
        int a, b;
    
        template <class Archive>
        void serialize( Archive & ar )
        {
    
          ar.setNextName("a");
          ar(a);
          ar.setNextName("b");
          ar(b);
        }
    };
    
    int main(int argc, char *argv[])
    {
        Foo foo(1, 2);
        cereal::XMLOutputArchive out(std::cout);
    
        out.setNextName("Foo");
        out(foo);
    }
    

    Ausgabe:

    <?xml version="1.0" encoding="utf-8"?>
    <cereal>
    	<Foo>
    		<a>1</a>
    		<b>2</b>
    	</Foo>
    </cereal>
    


  • Lua oder AngelScript sind auch gute Kandidaten. Weil dann wird einem auch gleich bewusst, was für andere geile Möglichkeiten man damit hat. 👍



  • da gibt es scheinbar eine Vielzahl sowas zu lösen. AngelScript kommt mir bekannt vor (programmieren von Mods für Spiele?). Ich werde mich da mal hineinlesen.


Anmelden zum Antworten