static member-variable im header initialisieren?!
-
Rein aus dem Bauch heraus würde ich sagen: Nein, es ist nicht möglich. Du musst die Variable ja irgendwo definieren, wenn du das im Header tust, ist sie in jeder Übersetzungseinheit drin, was Konflikte gibt.
-
class statictest { private: static int a; static int b; public: statictest() {} ~statictest() {} static int dblA(){return a*2;} static void prt(){cout << a << ' ' << b << endl;} }; int statictest::a = 5; int statictest::b = 2;erzeugt beim linken dann folgende errors:
./obj/testclass1.o: (.data+0x0): multiple definition of `statictest::a' ./obj/testclass2.o: (.data+0x0): first defined here ./obj/testclass1.o: (.data+0x4): multiple definition of `statictest::b' ./obj/testclass2.o: (.data+0x4): first defined here ./obj/testclass2.o: (.data+0x0): multiple definition of `statictest::a' ./obj/testclass2.o: (.data+0x0): first defined here ./obj/testclass2.o: (.data+0x4): multiple definition of `statictest::b' ./obj/testclass2.o: (.data+0x4): first defined here ./obj/functions.o: (.data+0x0): multiple definition of `statictest::a' ./obj/testclass2.o: (.data+0x0): first defined here ./obj/functions.o: (.data+0x4): multiple definition of `statictest::b'aber kann ich dem compiler nicht sagen, dass ich im header diese initialisierung nur einmal haben möchte?
-
Nein, das geht nicht. Du könntest die Klasse höchstens zu einem Template machen, dann wird das mit der ODR etwas freier gehandhabt IIRC. Aber das wäre einfach grober Unfug, wenn die Klasse kein Template sein muss.
Warum machst du es nicht einfach, wie es sich gehört in eine statictest.cpp-Datei?
-
es gibt hier einen einfachen grund.
das makefile muss sich bei uns jeder in der firma selbst verwalten und wenn man dann so "hilfsklassen" für sich und die anderen bastelt, hätte eine reine header-datei den vorteil, dass man diese nur inkludieren, aber nicht ins makefile einpflegen muss.
oder ist eine hilfsklasse von einer anderen abhängig, dann muss man diese file ja auch im makefile angeben werden und das alles wäre eben gelöst, AUßER man verwendet static members, dann hat man ein ordentliches problem.
-
Dumme Frage von mir, aber sollte das nicht durch einen Include-Guard behoben werden?
#ifndef _H_XYZ_GUARD__ #define _H_XYZ_GUARD__ // Klasse // Statische Variablen #endifGrüssli
-
Dravere schrieb:
Dumme Frage von mir, aber sollte das nicht durch einen Include-Guard behoben werden?
Nene, damit wird ja nur verhindert, dass die Header-Datei mehrfach in einer Cpp-Datei eingebunden wird. Aber das Problem ist ja, dass die Headerdatei in verschiedenen Cpps eingebunden wird; bzw das ist eigentlich kein Problem, sondern dass in jeder Cpp-Datei dann schlussendlich die Definition der statischen Variable landet

-
Sofern die const sind, kannst du die Dekleration in der Klasse machen:
class statictest { private: static const int a = 5; static const int b = 2; public: statictest() {} ~statictest() {} static int dblA(){return a*2;} static void prt(){cout << a << ' ' << b << endl;} };
-
drakon schrieb:
Sofern die const sind, kannst du die Dekleration in der Klasse machen:
die idee hatte ich auch schon bzw. hat mich das npos vom stl-string auf die idee gebracht, aber da ich leider auch zur laufzeit die werte ändern muss...

-
Badestrand schrieb:
Dravere schrieb:
Dumme Frage von mir, aber sollte das nicht durch einen Include-Guard behoben werden?
Nene, damit wird ja nur verhindert, dass die Header-Datei mehrfach in einer Cpp-Datei eingebunden wird. Aber das Problem ist ja, dass die Headerdatei in verschiedenen Cpps eingebunden wird; bzw das ist eigentlich kein Problem, sondern dass in jeder Cpp-Datei dann schlussendlich die Definition der statischen Variable landet

Ach stimmt ja ... mist
Naja, wenn die static Variablen nicht Konstant sind, dann gebe es natürlich die Möglichkeit, dass du manuell eine Funktion für die Initialisierung aufrufst.
class XYZ { public: static void init_class(); };Oder du machst die Klasse als Singleton, meiner Meinung nach hier die Beste Lösung, wenn du auf das .cpp verzichten möchtest.
Grüssli
-
Dravere schrieb:
Naja, wenn die static Variablen nicht Konstant sind, dann gebe es natürlich die Möglichkeit, dass du manuell eine Funktion für die Initialisierung aufrufst.
class XYZ { public: static void init_class(); };geht so leider auch nicht, weil man die static members als eine art globale variable im cpp-file eigentlich anlegen muss.
-
wenn der berg nicht zum propheten kommt, dann...
verzichte auf die variablen!
class HeaderOnly { static int& m_a () { static int a_; return a_; } static int& m_b () { static int b_; return b_; } public: static int dblA(){return m_a()*2;} static void prt() {cout << m_a() << ' ' << m_b() << endl;} };oder tu dir die arbeit mit dem makefile an.
-
DANKE

ja das ist die lösung für das problem, weil in m_a() kann ich auch die variablen initialisieren.sollte man bei dieser lösung noch überlegungen anstellen bzgl. performance gegenüber einer "normalen" static-member lösung oder wird das eher nicht ins gewicht fallen?
-
War da nicht was mit inline Funktionen und static membern in verschiedenen Ueberseztungseinheiten? Mir ist da irgendwas im Gedaechtnis, dass bei inline Funktionen fuer jede Uebersetzungseinheit eigene statische variablen angelegt werden, so dass m_a nicht immer auf die selbe Variable a_ referenziert. Angabe ohne Gewaehr, vielleicht weiss da jemand genaueres...
-
es ist sichergestellt, dass statische variablen in inline-funktionen immer auf dasselbe objekt verweisen.
die ausnahme wäre, wenn die funktion interal linkage hätte, was normalerweise bei
static-funktionen auch der fall wäre, aber nur, wenn sie nicht im klassenscope deklariert werden.
-
queer_boy schrieb:
es ist sichergestellt, dass statische variablen in inline-funktionen immer auf dasselbe objekt verweisen.
Jedoch siehts bei static membern in verschiedenen Übersetzungseinheiten anders aus. Genau wie bei gloables Variablen, ist auch hier die Initalisierungsreihenfolge nicht definiert.
Edit: Uups, darüber redet ihr ja gar nicht
