static class und Übersetzungseinheiten
-
Hallo,
folgendes sei gegeben:
test.h
struct test { static userdefined_class; // Ersatz einer globalen Variablen }
Nun wird mittels
test::userdefined_class
in verschiedensten Einheiten (einheit1.cpp form1.cpp keineahnungwas.cpp nochnegroßeunit.cpp) verwendet.
Ist hier gewährleistet das userdefined_class immer das gleiche Objekt ist ?
Bei:
test2.h
int global;
kann es ja passieren, das jede Unit ihre eigene Version hat. Wie schaut das bei obrigen Konstrukt aus ?
-
Hi,
ich würde tippen, dass es (analog zu Deinem int-Beispiel) davon abhängt, ob Du in einer Übersetzungseinheit per "extern" das Objekt in der anderen Unit referenzierst oder ein neues definierst.
Also:
a)// In a.cpp: int global; // lege ein int an // in b.cpp int global; // lege ein int an
gibt beim Linken vermutlich einen "duplicate symbol"-Fehler o.ä., während
// In a.cpp: int global; // lege ein int an // in b.cpp extern int global; // beziehe Dich auf ein int, das woanders angelegt wurde
dafür sorgt, dass in b.cpp sozusagen nur mit einer Referenz (die allerdings erst der Linker auflöst) auf das a.cpp::global-int" gearbeitet wird.
Ein bischen Schwierigkeiten macht mir bei Deinem Beispiel, dass in C "static" ja auch "internal linkage" bedeutet, was automatisch einen "Verweis per extern" ausschließt .... aber da hat sich C++ evtl. geändert.
Gruß,
Simon2.
-
Ja, nun wird aber keine Instanz der Klasse angelegt sondern mittels
test::userdefined_class zugegriffen
-
Knuddlbaer schrieb:
Ja, nun wird aber keine Instanz der Klasse angelegt sondern mittels
test::userdefined_class zugegriffen
Allerdings muß der Linker auch eine entsprechende Definition finden - so mußt Du in Deinem Beispiel ja irgendwo auch ein
int test::userdefined_class;
in einer Unit aufnehmen.
... und ich vermute deswegen, dass Du mit einer Deklaration (in der "zweiten" Unit) wie
extern int test::userdefined_class;
klarkommst.
aber ich habe noch nicht ausprobiert/nachgeschlagen, ob das (so) funktioniert (wie ich mir das vorstelle).Gruß,
Simon2.
P.S.: Irgendwie ist mir noch nie aufgefallen, dass es hier in C auch sowas wie eine "C++-Referenz" gibt.
-
Knuddlbaer schrieb:
Ist hier gewährleistet das userdefined_class immer das gleiche Objekt ist ?
genauso wie bei
test2.h
int global;
ist immer garantiert dass es 1 objekt nicht doppelt geben kann. Das verlangt die ODR.
kann es ja passieren, das jede Unit ihre eigene Version hat. Wie schaut das bei obrigen Konstrukt aus ?
nein, kann nicht passieren.
man kann aber natuerlich jeder UeE eine eigene global variable geben, indem man sie in einen unnamed namepace packt.. aber das wird dann echt haesslich.
eine deklaration ala
extern int foo::bar;
braucht man uebrigens nicht. foo::bar ist in der klassendefinition von foo bereits deklariert.
-
Mal nebenbei:
struct test { static userdefined_class; // Ersatz einer globalen Variablen }
Fehlt hier nicht der Name der Variablen, die den Typ userdefined_class haben soll (oder der Typ der Variablen, die userdefined_class heisst)?
-
Shade Of Mine schrieb:
...
eine deklaration ala
extern int foo::bar;
braucht man uebrigens nicht. foo::bar ist in der klassendefinition von foo bereits deklariert.Jupp, habe ich auch gerade festgestellt.
Ist auch klar - habe mir irgendwie selbst mit dem "int global" und dem "extern" ein Bein gestellt.
Aber da ein struct/class uns die Möglichkeit gibt, zwischen Deklaration und Definition/Instantiierung zu unterscheiden, braucht's das gar nicht mehr explizit (im Gegensatz zum "int global")....Gruß,
Simon2.
-
Simon2 schrieb:
Aber da ein struct/class uns die Möglichkeit gibt, zwischen Deklaration und Definition/Instantiierung zu unterscheiden, braucht's das gar nicht mehr explizit (im Gegensatz zum "int global")....
bei einer "normalen varialen definition" kann man auch problemlos zwischen deklaration und definition unterscheiden:
int global; //definition extern int global; //deklaration
genauso wie bei einer klasse:
class C; //deklaration class C {}; //definition
bei einer static variable innerhalb einer klasse auch:
class C{ static int foo; //deklaration }; int C::foo; //definition
-
Shade Of Mine schrieb:
Simon2 schrieb:
Aber da ein struct/class uns die Möglichkeit gibt, zwischen Deklaration und Definition/Instantiierung zu unterscheiden, braucht's das gar nicht mehr explizit (im Gegensatz zum "int global")....
bei einer "normalen varialen definition" kann man auch problemlos zwischen deklaration und definition unterscheiden:
int global; //definition extern int global; //deklaration
...
Eben ! Wie ich gesagt habe: Per "extern" unterscheidet man explizit die Deklaration von der Definition.
und deswegen auch andersherum: Weil ein
struct { static int a; } A;
in C++ eine reine Deklaration ist, braucht man hierbei kein "extern" mehr, um diese Tatsache auszudrücken.
Gruß,
Simon2.