Linken von statischen Variablen
-
Hallo,
mal angenommen ich habe einen Header in dem eine Klasse mit einer statischen variable deklariert wird und die Variable wird dort auch definiert:A.h:
class A{ public: static int i; } int A::i;Wenn ich jetzt zwei verschiedene Programmteile habe, die beide A::i verwenden, teil1.cpp und teil2.cpp und ich das Gesamtprojekt compiliere:
cc teil1.cpp teil2.cppDann bezeichnet A::i doch in beiden Teilen UNTERSCHIEDLICHE Speicherplätze, oder? Wenn ja, was kann man dagegen tun? Ich könnte die Definition von A::i natürlich nochmal in ein einzelnes Modul packen und das dem Linker geben, aber das kommt mir unnötig umständlich vor, für eine einzelne Variable. Ich habe mal was vom Schlüsselwort extern gehört, bin mir aber nicht sicher, ob das hier das richtige wäre.
-
Karl R schrieb:
Ich könnte die Definition von A::i natürlich nochmal in ein einzelnes Modul packen und das dem Linker geben, aber das kommt mir unnötig umständlich vor, für eine einzelne Variable.
Aber ist der normale Weg. Ausser du hast eine statisch konstante integrale Variable, dann braucht es keine Definition ausserhalb der Klasse.
Allerdings muss man mit solchen statischen Variablen extrem aufpassen, da man grob gesagt, eigentlich erst davon ausgehen kann, dass die Variable richtig vorhanden ist, wenn eine Funktion aus der entsprechenden Übersetzungseinheit aufgerufen wurde.
Um sich das Leben zu vereinfachen, kann man das ganze in eine Funktion packen:
class MyClass { public: static int& myVar() { static int i = 0; return i; } };Die statische Variable wird ganz sicher vorhanden sein, wenn man zum ersten Mal die Funktion aufruft. Auch kann man alles in den Header schreiben. Bei der Verwendung sehen die Klammern vielleicht nicht ganz optimal aus, aber wirklich stören tun sie wohl nicht.
Grüssli
-
Dravere schrieb:
Um sich das Leben zu vereinfachen, kann man das ganze in eine Funktion packen:
class MyClass { public: static int& myVar() { static int i = 0; return i; } };Hey, das ist toll. So fallen bei meinem Projekt eine Menge Schwierigkeiten weg. Danke!
-
Oft spricht auch nichts dagegen, eine Variable gar nicht in der Klasse, sondern global in der jeweiligen Übersetzungseinheit zu speichern. Das hat den Vorteil, dass du dir gewisse Abhängigkeiten sparst und damit bei Änderungen weniger neu kompilieren musst. Hängt natürlich auch von dem jeweiligen Fall ab. Mich würde trotzdem interessieren, wieso bei dir eine Definition in der Übersetzungseinheit einen solchen Mehraufwand mit sich bringen soll.
Siehe auch http://www.c-plusplus.net/forum/viewtopic-var-t-is-237943.html...
-
Nexus schrieb:
Mich würde trotzdem interessieren, wieso bei dir eine Definition in der Übersetzungseinheit einen solchen Mehraufwand mit sich bringen soll.
Das liegt daran, dass besagte Klasse nur so kurze Methoden hat, dass ich für sie gar keine Übersetzungseinheit eigene habe, sondern alles inline gemacht habe. Ich würde also quasi eine neue Übersetzungseinheit mit nur zwei Zeilen, nämlich
A.cpp:
#include "A.h" int A::i;machen. Das ist natürlich nicht viel Aufwand, sondern ich fand eher, dass es irgendwie lächerlich aussieht.
-
Ah okay. Um die Klasse klein zu halten, kannst du das schon so machen. Solange du die Funktionen selten änderst, wenige Dateien von deinem Header abhängig sind oder deine Kompilierzeiten sowieso kurz sind, ist das auch gar kein Problem.
Ich selber habe mir angewöhnt, die meisten Funktionen in der .cpp-Datei zu definieren. Bei ganz kleinen Klassen sind dann teilweise mehrere Klassen in einem Header und entsprechend mehrere Funktionsdefinitionen in der Implementierungsdatei. Falls man Templates verwendet, ist das sowieso wieder was anderes...
Das Ganze ist wie so vieles auch ein wenig Geschmackssache. Ich habe es zum Beispiel lieber, wenn ich in der Headerdatei gerade einen schönen Überblick über die Deklarationen habe und nicht unnötige Implementierungsdetails sehe.