Initialisierung von static vector<string>



  • Soll der Vektor nach der Initialisierung später geändert werden oder ist das eine Art konstante Lookup-Tabelle? Falls letzteres, würde ich dir von std::vector und std::string abraten, da diese eine dynamische Initialisierung erfordern. Mach's so:

    // Header-Datei (falls noetig)
    extern const char* const table[4];
    
    // CPP-Datei...
    extern const char* const table[4] = {
      "foo", "bar", "dies", "das"
    };
    

    Falls Du die Tabelle nur "privat" in einem Modul verwenden möchtest, kannst Du Dir das mit der Headerdatei und dem "extern" natürlich sparen.



  • Hallo,

    vielen Dank für die Antworten. Die Klasse soll für das Projekt die Fehlermeldungen an zentraler Stelle sammeln. Damit die Fehlerklasse sowohl abgeleitet oder auch als lokale Variable eingebunden werden kann, möchte ich keinen Singleton verwenden. Eine Singleton Lösung, mit der die Fehlerklasse die eigenen lokalen Membervariablen einbindet, würde vom Entwurf wahrscheinlich aber auch funktionieren. Mein erster Gedanke war aber, es mit einer statischen Membervariablen zu versuchen. Das Problem ist aber, daß statische Membervariable bereits existieren, bevor eine Instanz der Klasse erzeugt wird. Also muss ich mich um die Initialisierung der statischen Membervariablen selbst kümmern. Ein Zugriff auf eine nicht-initialiserte Vecor-Membervariable führt bekanntlich zum Absturz, was ich mir auch erst noch einmal in Erinnerung rufen musste.

    @Nexus: ich bin mir nicht sicher, dies funktionieren wird, da auch hier vecor als statische Variable händisch initialisiert werden muss, oder?

    @muffmolch: boost scheidet in den Projekt wegen Platzmangel aus

    @CStoll: bei statischen Membervariablen wird der Standard-Konstruktor nicht automatisch aufgerufen

    @krümelkacker: nein, es soll eine Klasse sein, die eine bestimmte Anzahl von Meldungen während der Laufzeit des Programms speichert.

    Gruß

    Peter



  • Plumpsklo schrieb:

    @CStoll: bei statischen Membervariablen wird der Standard-Konstruktor nicht automatisch aufgerufen

    Doch, selbstverständlich wird er.

    #include <iostream>
    
    struct A { A() { std::cout << "A Konstruktor\n"; } };
    
    struct B
    {
        static A a;
    };
    
    A B::a;  // <-- Definition
    
    int main()
    {
        std::cout << "Main, erste Zeile\n";
    }
    

    Ausgabe:

    A Konstruktor
    Main, erste Zeile
    


  • Plumpsklo schrieb:

    @CStoll: bei statischen Membervariablen wird der Standard-Konstruktor nicht automatisch aufgerufen

    Doch, wird er!

    edit: sorry, hatte den Post wohl etwas lange offen 😉 ipsec hat die ctor-Tatsache bereits berichtigt...



  • Hallo,

    jetzt bin ich verwirrt. Mein Programm ist abgestürzt, als ich mit einem Iterator auf ein normal deklariertes static std::vectorstd::string zugreifen wollte. Erst der Kunstgriff mit der Pseudo-Initialisierung und dem anschließenden clear() hat funktioniert.

    Gruß

    Peter



  • struct A { A() { std::cout << "A Konstruktor\n"; } }; 
    static A a;
    struct B { 	static A a;  }; 
    A B::a;  // <-- Definition 
    static std::vector< std::string > testVec(2, "test");
    
    int main( int, char * )
    {
    	std::cout << "main" << std::endl;
    	std::cout << testVec.size() << std::endl;
    	BOOST_FOREACH( const std::string & str, testVec )
    		std::cout << str << std::endl;
    }
    

    liefert unter msvc 9:

    A Konstruktor
    A Konstruktor
    main
    2
    test
    test
    


  • muffmolch schrieb:

    struct A { A() { std::cout << "A Konstruktor\n"; } }; 
    static A a;
    struct B { 	static A a;  }; 
    A B::a;  // <-- Definition 
    static std::vector< std::string > testVec(2, "test");
    
    int main( int, char * )
    {
    	std::cout << "main" << std::endl;
    	std::cout << testVec.size() << std::endl;
    	BOOST_FOREACH( const std::string & str, testVec )
    		std::cout << str << std::endl;
    }
    

    liefert unter msvc 9:

    A Konstruktor
    A Konstruktor
    main
    2
    test
    test
    

    GCC auch.
    (mecker bei "int main( int, char * )")



  • Plumpsklo schrieb:

    vielen Dank für die Antworten. Die Klasse soll für das Projekt die Fehlermeldungen an zentraler Stelle sammeln. Damit die Fehlerklasse sowohl abgeleitet oder auch als lokale Variable eingebunden werden kann, möchte ich keinen Singleton verwenden. Eine Singleton Lösung, mit der die Fehlerklasse die eigenen lokalen Membervariablen einbindet, würde vom Entwurf wahrscheinlich aber auch funktionieren. Mein erster Gedanke war aber, es mit einer statischen Membervariablen zu versuchen. Das Problem ist aber, daß statische Membervariable bereits existieren, bevor eine Instanz der Klasse erzeugt wird. Also muss ich mich um die Initialisierung der statischen Membervariablen selbst kümmern. Ein Zugriff auf eine nicht-initialiserte Vecor-Membervariable führt bekanntlich zum Absturz, was ich mir auch erst noch einmal in Erinnerung rufen musste.

    Dir ist ein Singleton zu global (schonmal ein löblicher Ansatz), aber stattdessen verwendest du statische Member, die genauso global gültig sind? Das mußt du mir mal genauer erklären.

    @CStoll: bei statischen Membervariablen wird der Standard-Konstruktor nicht automatisch aufgerufen

    Klar wird er aufgerufen, wie dir schon mehrere Nutzer bewiesen haben.
    Probleme kann es nur geben, wenn verschiedene globale/statische Variablen in unterschiedlichen Übersetzungseinheiten initialisierst, die voneinander abhängen. Aber dein bisheriges Beispiel sieht nicht danach aus.



  • ^^^^

    Hallo,

    mir ist der Sigleton nicht zu global, sondern von der Implementierung ein wenig zu unpraktisch. Sinn dieser Anwendung soll es ja gerade sein, daß unabhängig davon, wie oft und auf welche weise die Klasse benutzt wird, die vector-variable für alle Instanzen die selbe ist.

    Leider bin ich in C++ noch nicht so firm, daher weiss ich nicht, warum

    [i] (static) [/i]std::vector<std::string> classname::varname; // definition
    

    zu einem nicht initialisierten Vektor führt, während eine Initialisierung mit

    const char *var_init[]={Val_1, Val_2 Val_3};
    [i] (static) [/i]std::vector<std::string> classname::varname(var_init, var_init+3); // definition
    

    den Vektor korrekt initialisiert, wenngleich auch mit Werten, die ich nicht haben möchte.

    Was müsste ich denn in die Klammern schreiben, damit der Vektor mit 0 Elementen initialisiert wird?

    Gruß

    Peter



  • Laut C++ Standard sollte auch der erste Aufruf einen komplett initialisierten vector<> anlegen, also läuft bei deinem Code vermutlich etwas anderes schief (auf Anhieb würde ich auf Probleme mit der Initialisierungs-Reihenfolge von globalen Objekten tippen).

    Ansonsten lässt sich das Singleton-Konzept auch für spezielle Anforderungen variieren:

    class classname
    {
      static vector<string>& log()
      {
        static vector<string> variable;
        return variable;
      }
      ...
    };
    

Anmelden zum Antworten