Innerer Daten oder globaler?
-
Hallo,
ich stehe vor einer kleinen Designentscheidung und würde gerne euren Rat hören. Wenn ich Daten"typen" habe (enums, structs, #define), die nur Bedeutung für eine Klasse haben (vor allem als Parameter für Methoden dieser Klasse, sollte ich diese Typen dann global in dem Headerfile der Klasse definieren oder IN der Klasse selber?
Zur Veranschaulichung:
enum FOO_WORKING_TYPE { FOO_WORKING_A, FOO_WORKING_B }; class Foo { public: Foo(FOO_WORKING_TYPE f); };Im Moment definiere ich alle Datentypen, die von Foo verwendet werden global
außerhalb der Klasse. Ich könnte sie jedoch auch innerhalb der Klasse definieren, dann hätte ich quasi Foo:WORKING_TYPE statt FOO_WORKING_TYPE etc.
Was findet ihr besser?
-
mari22 schrieb:
. Wenn ich Daten"typen" habe (enums, structs, #define)
#definerepräsentiert keinen Datentyp, sondern macht nur eine textuelle Ersetzung. Siehe mein erster Post hier.mari22 schrieb:
Was findet ihr besser?
Keine Frage, innerhalb der Klasse. Ansonsten verschmutzt du nur den globalen Namensraum. Und wieso ausserhalb, wenn die Daten dort gar nie gebraucht werden? Dann soll sie dort auch niemand kennen.
-
Nexus schrieb:
repräsentiert keinen Datentyp, sondern macht nur eine textuelle Ersetzung.
Drum habe ich ja extra "typen" in Gänsefüßchen geschrieben.

Ich habe jetzt die Typen in den public Bereich der Klasse verschoben, nur leider kriege ich jetzt ne Fehlermeldung:
class Foo { private: CullingDesc cullingDesc; // << hier gibts die Fehlermeldung public: enum CULLING_TYPE { CULLING_NONE, CULLING_QUADTREE }; struct CullingDesc { CULLING_TYPE cullingType; UINT subDivisions; }; };Fehler:
error C2146: syntax error : missing ';' before identifier 'cullingDesc'
Die Fehlermeldung versteh ich nicht. Ich habe irgendwas mit "undefined type" erwartet, weil ich den Typ ja erst später definiere... aber wieso diese Fehlermeldung mit dem ";"?
Ich habe versucht den Fehler mit einer Vorwärtsdeklaration zu beseitigen, also unmittelbar vor CullingDesc cullingDesc; das hier geschrieben:
struct CullingDesc;Nur dann bekomme ich einen anderen Fehler:
error C2079: 'Foo::cullingDesc' uses undefined struct 'Foo::CullingDesc'
Was ist da der Fehler im Code?

-
mari22 schrieb:
Drum habe ich ja extra "typen" in Gänsefüßchen geschrieben.

Und ich hab es auch nicht ohne Grund erwähnt.
#defines, wenn sie nicht zu vermeiden sind (und sie sind es meistens) gehören nicht in Klassen. Sie nehmen weder Rücksicht auf Gültigkeitsbereiche noch auf Klassen, da so etwas im Präprozessor nicht existiert.mari22 schrieb:
Die Fehlermeldung versteh ich nicht. Ich habe irgendwas mit "undefined type" erwartet, weil ich den Typ ja erst später definiere... aber wieso diese Fehlermeldung mit dem ";"?
Wahrscheinlich nimmt der Compiler an, es handle sich um eine Anweisung, da er ja nicht weiss, dass
CullingDesceinen Typ darstellt.mari22 schrieb:
Nur dann bekomme ich einen anderen Fehler:
error C2079: 'Foo::cullingDesc' uses undefined struct 'Foo::CullingDesc'
Was ist da der Fehler im Code?

Steht ja da. Die Struktur ist zu diesem Zeitpunkt noch nicht vollständig definiert.
-
Genau deshalb mach ich doch die Forward Declaration. Wie behebe ich denn nun den Fehler?
-
mari22 schrieb:
Genau deshalb mach ich doch die Forward Declaration. Wie behebe ich denn nun den Fehler?
Indem du die Struktur
vollständigdefinierst, und zwar, bevor du Objekte von ihr deklarierst.Vorwärtsdeklarationen besitzen nur die Information, dass ein
struct-Typ mit diesem Namen existiert.
-
Ok ich denke ich weiß nun den Grund des Fehlers. Da cullingDesc kein Pointer ist, brauch der Compiler die Definition von CullingDesc um die Größe zu ermitteln. Eine Vorwärtsdeklaration reicht also nicht. Die Frage bleibt aber: Wie behebe ich diesen Fehler? (die Struktur CullingDesc soll weiterhin in der Klasse bleiben)
-
Nexus schrieb:
Indem du die Struktur
vollständigdefinierst, und zwar, bevor du Objekte von ihr deklarierst.Naja, aber das objekt ist ja im private bereich und der typ im public bereich. muss ich dann extra wegen den einen typ den public bereich vor den private bereich ziehen? (das fände ich ziemlich hässlich, da ich in meinem projekt IMMER zuerst mir private beginne) gibts da nen anderen trick?
-
mari22 schrieb:
gibts da nen anderen trick?
Nein. Aber so hässlich ist das nicht, in vielen Klassen werden die Zugriffsspezifizierer noch viel häufiger abgewechselt.
-
was macht das für einen sinn, eine struktur mit zwei membern innerhalb einer klasse zu definieren ?

mach doch zwei membervariable der klasse daraus.
-
wattsafugga schrieb:
was macht das für einen sinn, eine struktur mit zwei membern innerhalb einer klasse zu definieren ?
Wenn die Struktur eine logische Einheit bildet, kann es schon Sinn machen. Zudem hat man es leichter, wenn plötzlich noch mehr Variablen dieses Typs dazu kommen.