Initialisierung von static vector<string>
-
Plumpsklo schrieb:
Das ist zwar nett, belegt aber den Vektor gleich mit Werten, die ich dort nicht haben möchte. Deswegen habe ich eine statische Memberfunktion geschrieben, die vor main() erst einmal clear() aufruft.
Wenn du einen leeren Vector benötigst, ist es imho sinnfrei, sich erst einen vollen Vector zu besorgen und diesen dann zu leeren. Leg doch einfach einen leeren vector an, das reicht völlig:
std::vector<std::string> classname::varname; // definition
-
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 testGCC 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; // definitionzu 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); // definitionden 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; } ... };