Ansammlung von Funktionen in header Datei?
-
CStoll schrieb:
Zudem wundert mich, dass Klassendefinition nicht in Headerdateien gehört.
Weil eine Deklaration wäre ja:class hallo;und eine Definition schon:
class hallo { private: int a; };Und die Definition steht bei mir immer in den Headern- das haben wir sogar in der Schule gelernt.
Das sind beides Deklarationen (das erste eine Forward-Deklaration der Klasse, das zweite deklariert deren Member - die Definition geschieht später (statische Member und Methoden mußt du nochmal explizit angeben, normale Member werden implizit definiert, wenn du ein Objekt dieser Klasse anlegst).
das ist eine definition. und auch für die member der klassen kann man das definition nennen (wie es der standard auch tut, und nicht bloß deklaration). nur statische member werden in einer klassendefinition bloß deklariert und müssen danach (nicht nochmal, sondern zum ersten mal) definiert werden. dein erstes beispiel
class X;muss noch nichtmal eine forward-deklaration sein, es kann auch einfach eine redeklaration einer bereits definierten klasse sein.regel: eine deklaration _ist_ eine definition, außer (unter anderem) sie deklariert eine statische elementvariable (siehe v.a.: 3.1/2 und 3, 9.1., zu statischen membern: 9.4.2/2)
-
irgendwie hat mich das jetzt etwas durcheinander gebracht^^
http://www.c-plusplus.net/forum/viewtopic-var-t-is-61231.html
Dort wird ganz klar gesagt, dass Deklarieren nur heisst einen bestimmten Namen in einem Scope zu reservieren.
extern int a; void foo(int); class hallo;Oder etwas in der Richtung.
Definieren heisst, dass der Compiler speicher belegt.
Also welche der Aussagen stimmt jetzt?^^class hallo { private: int a; };Belegt ja in dem Sinne auch noch keinen Speicher sondern gibt nur die Namen der Member der Klasse bekannt.
Also kann letztriger Codeschnipsel doch in die Header <-- Ist also eine klare DEKLARATION?
Doch was käme dann von der Klasse 'hallo' noch in die ausgelagerte Cpp?
-
Ja, das kann schonmal zu Verwirrungen führen. Die Klassendefinition gehört in den Header (aus technischer Sicht würde ich das auch als Deklaration ansehen), in die CPP gehört die Definition der statischen Member und Methoden (die bei dieser Klasse nicht existieren):
//Klassen-Definition - gehört in den Header class test { int i; static int s; public: void print(); }; //Member-Definitionen - gehören in die CPP int test::s; void test::print() { cout<<s<<" "<<i<<endl; } //test::i muß nicht gesondert definiert werden - das lebt innerhalb der 'test'-Objekte, die du irgendwo im Programm anlegen kannst
-
Das wiederum würde aber auch bedeuten, dass alle Elementfunktionen ausgelagert werden müssen.
Also sollte KEINE davon innerhalb der Klasse definiert werden, wie man es auch häufig im Netz sieht.
Sondern immer mit dem Zugehörigkeitsoperator in eine andere Datei - die Cpp-Datei?Also wäre die Regel auch:
Keine Elementfunktionen innerhalb der Klasse definieren.
?^^
-
777 schrieb:
Also wäre die Regel auch:
Keine Elementfunktionen innerhalb der Klasse definieren.
?^^
Nicht ganz - inline Funktionen dürfen (und müssen) im Header definiert werden (weil der Compiler den Quelltext benötigt, um sie inline ersetzen zu können). Und Methoden, die direkt in der Klassendefinition definiert werden, gelten automatisch als inline.
-
Also dürfen in den Header nur Deklarationen, mit großer Ausnahme von Inlinefunktionen?

Okay... super- ich denk ich habs verstanden xD
-
777 schrieb:
Definieren heisst, dass der Compiler speicher belegt.
vielleicht könnte man diesen punkt genauer herausarbeiten als: definieren heißt, das an der stelle der definition dem compiler bekannt gemacht wird, wieviel speicher er für eine gewisse entität bereit stellen soll - was nicht heißt, dass er das auch machen muss. ein schönes beispiel dafür sind klassendefinitionen, ein anderes compiletime-konstanten, für die auch nur bei bedarf speicher reserviert wird. (wobei man sich da natürlich auf dünnem eis bewegt, der standard definiert definition als eine deklaration, bei der gewisse bedingungen nicht gegeben sind)
und um dich nochmal zu verwirren, du kannst in einem header auch "normale" definitionen haben, ohne je probleme beim kompilieren oder linken zu bekommen, z.b.
namespace { int i; } const int x = 42;
-
Was man kann und was man soll ist ja nochmal ein Unterschied.
Es geht mir ja darum zu lernen, was man sollte.
Und wenns besserer oder übersichtlicherer Programmierstil ist in die Header nur Deklarationen zu schreiben- so mach ich das
-
damit wollte ich nur sagen, dass es sehr wohl auch ausnahmen geben kann. die integralkonstante ist ein gutes beispiel dafür. in den header oder nicht? nein? was ist mit enums?
wichtig ist, die ODR zu kennen und zu wissen, was übersetzungseinheiten sind - und dass der präprozessor nur eine einfache textersetzungsmaschine ist.
-
queer_boy schrieb:
und um dich nochmal zu verwirren, du kannst in einem header auch "normale" definitionen haben, ohne je probleme beim kompilieren oder linken zu bekommen, z.b.
namespace { int i; } const int x = 42;Ja, absolut legal - und die Quelle von Verwirrungen sowohl für dich als auch für andere. (gerade beim ersteren hast du das Problem, daß jede ÜE ihre eigene Version von i bekommt (und du am Ende eine Ewigkeit auf der Suche nach dem Fehler verbringst)
@777: Wichtig ist vor allem, daß du (a) die Regeln der Sprache (hier vor allem die ODR) einhältst und (b) sauber programmierst.
Die ODR verbietet es, daß ein Objekt mehrfach im Programm definiert wird. Klassendefinitionen fallen nicht unter die strenge Auslegung der ODR, weil Klassen keine vollwertigen Objekte sind (sondern nur ein Bauplan für Objekte), inline-Funktionen und Templates werden vom Compiler und Linker gesondert behandelt.
(btw, statische Variablen und anonyme namespaces bleiben lokal in ihrer Übersetzungseinheit - damit stören sie den Linker ebenfalls nicht).Zur sauberen Programmierung gehört es unter anderem, globale Variablen zu vermeiden - und auch sauber zwischen Schnittstelle (Deklarationen etc. im Header) und Implementation (in einem eigenen CPP) zu trennen.