andere static variablen
-
Hallo! Ich hab ein Problem. Ich will innerhalb einer Klasse eine static variable benutzen. Bei normalen Datentypen habe ich das noch verstanden:
class XY{ static int x; int y; } XY.x=int(0);Aber jetzt will ich einen Zeiger benutzen und weiß nicht was ich als initialisierung schreiben soll:
class ABC{ static char* a; char*b; } ABC.a= //???
-
OK ich hab nen kleinen Fehler gemacht. meinte: XY::x und ABC::a aber das ändert auch nicht viel.
-
wieso willste die static machen ?
-
char* ABC::a = NULL;
-
Ich will eine für die Klasse wichtige Zeichenfolge speichern und will mich nicht mit einer globalen variable rumquälen.
außerdem habe ich herausgefunden, dass es mitABC::a=reinterpret_cast<char*>(0);funktioniert. Das sieht aber immer noch bescheuert aus. Kennt irgendjemand eine andere möglichkeit?
-
Willst du nicht einfach ein Char-Array direkt (ohne Zeiger) definieren?
Ansonsten nimmst du halt std::string.
-
qwertzuiopü+ schrieb:
Ich will eine für die Klasse wichtige Zeichenfolge speichern und will mich nicht mit einer globalen variable rumquälen.
Ne Konstante würde nicht reichen?
-
qwertzuiopü+ schrieb:
Ich will [...] mich nicht mit einer globalen variable rumquälen.
Ich hab mir selber schon ähnliche Gedanken gemacht. Hast du was gegen globale Variabeln, weil sie "zu präsent" sind, also erstens immer Speicher benötigen und zweitens von überall benutzt werden können? Denn Klassen sind, so gesehen, eigentlich auch global...
Oder hast du vielleicht mehrere Klassen und willst eine strikte Zugehörigkeit zu einer bestimmten Klasse betonen?
-
Nexus schrieb:
Ich hab mir selber schon ähnliche Gedanken gemacht. Hast du was gegen globale Variabeln, weil sie "zu präsent" sind, also erstens immer Speicher benötigen und zweitens von überall benutzt werden können? Denn Klassen sind, so gesehen, eigentlich auch global...
Oder hast du vielleicht mehrere Klassen und willst eine strikte Zugehörigkeit zu einer bestimmten Klasse betonen?
Es gibt mehrere Gründe statische Member den globalen Variablen vorzuziehen.
a) Man hat eine logische Zuordnung
b) Bei globalen Variablen ist die Initialisierungsfolge undefiniert (Was grade bei gegenseitigen Abhängigkeiten zu unschönen Fehlern führen kann die man so gut wie garnicht findet).cu André
-
asc schrieb:
b) Bei globalen Variablen ist die Initialisierungsfolge undefiniert
was aber völlig egal ist, weil alle globalen Variablen spätestens dann initialisiert sind, wenn "main" aufgerufen wird.
-
funky cat schrieb:
asc schrieb:
b) Bei globalen Variablen ist die Initialisierungsfolge undefiniert
was aber völlig egal ist, weil alle globalen Variablen spätestens dann initialisiert sind, wenn "main" aufgerufen wird.
Nein das ist nicht egal.
#include<iostream> struct Foo { Foo() { std::cout << "Hallo, nun gehts los!\n"; } } bar; int main() { return 0; }Was da passiert ist undefiniert.
-
Was soll da schlimmes passieren? Der Text wird ausgegeben und fertig.
-
funky cat schrieb:
Was soll da schlimmes passieren? Der Text wird ausgegeben und fertig.
Ich denke, dass er meint, dass es abhängig von der Implementation des Compilers entweder ausgegeben wird (ctor aufgerufen) oder eben nicht. Also nicht im Standard definiert ist, was da passiert.
-
Das ist doch Quatsch. Der Ctor vom globalen Objekt wird aufgerufen bevor main aufgerufen wird. Ich glaube nicht daß irgendein Compiler das nicht macht.
-
funky cat schrieb:
Das ist doch Quatsch. Der Ctor vom globalen Objekt wird aufgerufen bevor main aufgerufen wird. Ich glaube nicht daß irgendein Compiler das nicht macht.
Das ist auch nicht das Problem, drakon hat vielmehr noch nicht viel Bekanntschaft mit Dieter Nuhr geschlossen.
#include <iostream> struct Foo { Foo() { foovar = 1; } static int foovar; }; int Foo::foovar = 0; struct Bar { Bar() { barvar = Foo::foovar; } static int barvar; }; int Bar::barvar = 0; Foo foo; Bar bar; int main() { std::cout << Bar::barvar << std::endl; // 0 or 1? }
-
Hier noch ein einfacher zu verstehendes Beispiel:
struct Foo { Foo(); }; Foo bar; #include <iostream> Foo::Foo() { std::cout << "Hallo!\n"; } int main() {}$ g++ --version
i686-apple-darwin8-g++-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5370)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.$ g++ -Wall test.cpp -o test
$ ./test
Segmentation fault
-
Keine globalen Variablen. Fertig.
-
funky cat schrieb:
Das ist doch Quatsch. Der Ctor vom globalen Objekt wird aufgerufen bevor main aufgerufen wird. Ich glaube nicht daß irgendein Compiler das nicht macht.
Natürlich wird der Konstruktor aufgerufen, das ist auch nicht das Problem. Das Problem ist, dass nicht definiert ist, ob die globale Variable cout zu diesem Zeitpunkt bereits initialisiert ist, denn:
asc schrieb:
Bei globalen Variablen ist die Initialisierungsfolge undefiniert
-
Edit: Sorry, hatte nur auf die Änderungsmeldung geklickt, Antwort existerte schon xD... Wenn man unter Streß ist...
funky cat schrieb:
asc schrieb:
b) Bei globalen Variablen ist die Initialisierungsfolge undefiniert
was aber völlig egal ist, weil alle globalen Variablen spätestens dann initialisiert sind, wenn "main" aufgerufen wird.
Eben nicht. Wir hatten schon einmal im Projekt einen Fehler der annährend 2 Wochen zur Lokalisierung brauchte.
Nehmen wir einfach mal an wir haben zwei globale Instanzen von Klassen in unterschielichen Headern. Ein globales Objekt braucht im Konstruktor die Instanz des anderen:
// In unterschiedlichen Headern: A globalesA; B globalesB(globalesA);Nun kann folgendes passieren, da die Reihenfolge undefiniert ist:
a) "globalesB" hat eine gültige Instanz von A
b) "globalesB" hat eine ungültige Instanz von AViel Spaß bei der Fehlersuche.
Eine Mögliche Lösung ist folgende:
A& GetAInstanz() { static A a; return a; } B& GetBInstanz() { static B b(GetAInstanz()); return b; }Hier ist nämlich definiert: Anlage beim ersten Aufruf...
cu André
-
asc schrieb:
funky cat schrieb:
asc schrieb:
b) Bei globalen Variablen ist die Initialisierungsfolge undefiniert
was aber völlig egal ist, weil alle globalen Variablen spätestens dann initialisiert sind, wenn "main" aufgerufen wird.
Eben nicht. Wir hatten schon einmal im Projekt einen Fehler der annährend 2 Wochen zur Lokalisierung brauchte.
2 Wochen!!!? oha, vielleicht hättet ihr euch doch mal eher ansehen sollen, wie ein Debugger funktioniert.
Na gut. C++ Merkregel Nr. 7831: Niemals in konstruktoren von globalen Objekten andere globale Objete benutzen. Bei einfachen Variablen, int, long, double und so weiter sollte es aber trotzdem gehen.