Zieht ihr das voll durch? Trennung zwischen Header- und Sourcedateien.
-
Bin gerade dabei einige Klassen zu implementieren. Dabei komme ich immer wieder in die Versuchung (gerade bei recht kleinen Klassen die nicht viel Code/Logik beinhalten) die Implementierung gleich komplett in die Header Datei zu schreiben.
Wie macht ihr das denn? Zieht ihr das voll durch und trennt jede Pupsklasse in Header- und Sourcedatei? Oder überkommt es euch auch hin und wieder und ihr schreibt die Implementierung komplett in die Headerdatei? Gibts da ggf. sogar irgendwelche offiziellen Richtlinien?
-
Ich schreibe kleine Methoden schon manchmal in die Header-Dateien. Das ist auch eigentlich ganz sinnvoll, wenn du sie direkt in der Klasse definierst, da sie dann implizit als inline deklariert werden, was bei kleinen Methoden wie Gettern und Settern schon einen Vorteil bringen kann.
Bei größeren Methoden würde ich aber schon trennen, das hat auch den Vorteil, das nicht immer jede Datei, in der du den Header einbindest, neu übersetzt werden muss, wenn du nur die Implementierung änderst.
Felix
-
Besorgt euch VisualAssist X, dann könnt ihr alles in den Header schreiben und mit einem Mouseklick in den Source verfrachten lassen.
Umgekehrten Weg unterstützt VAX auch (Impl. im Source schreiben und per Mouseklick den Header erzeugen lassen). :pWer Implementierungen aus Fauelheit nicht in den Source schreibt, gehört verdroschen.

Außer in Templates würde ich sowas in meinen Projekten nicht akzeptieren.
-
ist mir eh ein rätsel, wie man ohen VA effizient programieren kann

aber jee setter und getter methode in die source datei auszulagern halte ich für übertrieben. Zumal ein inline vom compiler nicht zwingend umgesetzt wird... die wahrscheinlichkeit, wenn er dafür nicht erst in einer cpp datei suchen muss aber umso höhe rist
-
Artchi schrieb:
Besorgt euch VisualAssist X, dann könnt ihr alles in den Header schreiben und mit einem Mouseklick in den Source verfrachten lassen.
Ist ja alles schön und gut, aber das das Programm knapp 100 Euro kostet, schreckt mich eher ab...
-
muffmolch schrieb:
aber jee setter und getter methode in die source datei auszulagern halte ich für übertrieben. Zumal ein inline vom compiler nicht zwingend umgesetzt wird... die wahrscheinlichkeit, wenn er dafür nicht erst in einer cpp datei suchen muss aber umso höhe rist
Wie ist das zu verstehen? Du weißt, dass inline-Funktionen in den Header gehören? Wenn du dich darauf verlassen willst, dass der Compiler Implementationen aus cpp-Files herauszieht und irgendwoanders inline expandiert, kannst du das gerne tun, aber mit dem inline-Schlüsselwort hat das dann nichts mehr zu tun.
-
Bashar schrieb:
muffmolch schrieb:
aber jee setter und getter methode in die source datei auszulagern halte ich für übertrieben. Zumal ein inline vom compiler nicht zwingend umgesetzt wird... die wahrscheinlichkeit, wenn er dafür nicht erst in einer cpp datei suchen muss aber umso höhe rist
Wie ist das zu verstehen? Du weißt, dass inline-Funktionen in den Header gehören? Wenn du dich darauf verlassen willst, dass der Compiler Implementationen aus cpp-Files herauszieht und irgendwoanders inline expandiert, kannst du das gerne tun, aber mit dem inline-Schlüsselwort hat das dann nichts mehr zu tun.
die inline deklaration gehört in den header. aber du kannst dort auch jede methode als inline deklarieren und in der sourcedatei definieren. nur das letzteres nicht garantiert, dass sie auch wirklich ge-inlined werden. okay, das kann man nie...
-
muffmolch schrieb:
die inline deklaration gehört in den header. aber du kannst dort auch jede methode als inline deklarieren und in der sourcedatei definieren.
Du kannst diese Funktion dann auch nur in der Sourcedatei aufrufen, in der du sie definiert hast. (C++-Standard, 3.2 §3)
Deshalb gehört die Definition in den Header.
-
@Bashar: das war mir nicht bewußt. Ist aber im Nachhinein logisch und erklärt den Performance-Verlust, den ich hatte, als ich einige performance-relevante Methoden in die cpp ausgelagert hatte.
Allerdings konnte ich sehr wohl die Methoden auch von anderen Source-Dateien aus aufrufen. Wie sollte denn sonst folgendes funktioneren?//Klasse.h class Klasse { public: inline void foo(); }; //Klasse.cpp #include "Klasse.h" void Klasse::foo() {} //main.cpp #include "Klasse.h" int main() { Klasse a; a.foo(); }
-
EDIT: Das dürfte gar nicht funktionieren, denn
Standard, Paragraph 3.2.3 schrieb:
An inline function shall be defined in every translation unit in which it is used.
Felix
-
Phoemuex schrieb:
EDIT: Das dürfte gar nicht funktionieren, denn
Standard, Paragraph 3.2.3 schrieb:
An inline function shall be defined in every translation unit in which it is used.
Felix
mit vc funktioniert das bsp. jedenfalls! und "shall" ist nicht "has to".
Wenn ich Bashar richtig verstanden habe, so ignoriert der compiler die inlien Anweisung hier einfach.
-
muffmolch schrieb:
mit vc funktioniert das bsp. jedenfalls! und "shall" ist nicht "has to".
Seltsam. Manchmal legt der Compiler noch eine nicht geinlinete Version ab, wenn man beispielsweise die Adresse der Funktion für einen Funktionspointer benutzt. Vielleicht macht der VC das (bei deinen Einstellungen?) auch so, und deshalb findet der Linker die Definition.
BTW "shall" heißt "muss" im Sprachgebrauch des Standards.
-
also auch der gcc 3.x und 4.x und die intel compiler meckern nicht.
aber wie auch immer. das wesentliche, was ich mir nun merke ist:
"inline" methoden muessen immer im header definiert sein, wenn man sie wirklich inlinen moechte. ein inline in der source datei ist nur dann sinnvoll, wenn die funktion ausschließlich und nur dort verwendet wird. ansonsten würden std-konforme compiler fehlermeldungen liefern.back @topic:
da inline funktionen/methoden oft einen performanteren Code liefern und diese, wie der kleine Exkurs gezeigt hat, im Header definiert sein muessen, macht eine 100%ige Aufteilung von Deklaration im Header und Definition in der Source-Datei keinen Sinn.
-
ohne jetzt nachzusehen, tippe ich wiedereinmal darauf, dass der standard meint (wie so oft bei fehlern, die mehrere übersetzungseinheiten betreffen): "no diagnostics required".
-
Bashar schrieb:
BTW "shall" heißt "muss" im Sprachgebrauch des Standards.
naja eigentlich heißt shall sollen, also eher noch eine möglichkeitsform als es bei muss der fall ist.
-
Fake oder Echt schrieb:
Bashar schrieb:
BTW "shall" heißt "muss" im Sprachgebrauch des Standards.
naja eigentlich heißt shall sollen, also eher noch eine möglichkeitsform als es bei muss der fall ist.
Eigentlich, aber nicht im Standard
Du kannst es lesen als "X soll Y erfüllen, sonst ist X kein konformes Programm bzw. keine konforme Implementierung".
-
dann sind inline methoden irgendwie nur bei template-funktionen noetig (dort muss man sie, wenn man sie ausserhalb der klassendeklaration definiert, mit inline versehen, ansonten werden sie wie nicht inline funktionen behandelt. denn wen ich das richtig gesehen habe, so sind std-mäßig alle methoden, die im Header definiert werden zugleich inline...
stimmt das? wozu dann überhaupt inline?
-
nein, "standardmäßig" sind alle funktionen inline, die in einer klassendefinition definiert werden. alle anderen sind nicht inline. globale funktionen sind nicht inline (vor allem nicht, wenn man sie in einem header definiert), ebensowenig template-funktionen.
dann sind inline methoden irgendwie nur bei template-funktionen noetig
was meinst du damit?
inline hat auswirkungen auf zwei ebenen: einerseits ist es ein hinweis für den compiler, funktionsaufrufe durch die direkte ausführung des codes in der funktion zu umgehen (aber nur ein hinweis, kein muss!), andererseits ändert inline die regeln bezüglich der einmaldefinierung von funktionen. (konkret: du kannst inline-funktionen sooft definieren wie du willst, _aber_: du musst sie auch immer definieren, wenn du sie verwendest)
-
okay. ich meinte jetzt ausschließlich klassenmethoden.
wie ist es beim vorherigen Bsp://Klasse.h class Klasse { public: inline void foo() {} //hier es überflüssig, da es implizit gesetzt wird void foo2(); }; void Klasse::foo() {} //bisher dacht eich, dass diese methode ebenfalls implizit inline ist, ist sie das nicht?ds mit den templtes hatt eich falsch in Erinnerung, das galt für template methoden... nicht für Klassen...
[/cpp]
-
BugJoe schrieb:
Wie macht ihr das denn? Zieht ihr das voll durch und trennt jede Pupsklasse in Header- und Sourcedatei? Oder überkommt es euch auch hin und wieder und ihr schreibt die Implementierung komplett in die Headerdatei? Gibts da ggf. sogar irgendwelche offiziellen Richtlinien?
Um auf die Ursprungsfrage wieder zurückzukommen. Ich benutze überhaupt keine inline. Einerseits ist mir auch bekannt, dass getter & setter ohne Probleme im Header implementiert werden können. Andererseits kann es auch passieren, wenn z. Bsp. alles im Header für inline erklärt wird, der Code langsamer wird.
Sollte ich doch mal in die Versuchung kommen Funktionen inline zu machen, dann würde ich mit einem Profiler versuchen, erstmal herausfinden wo meine Programm sich am häufigsten befinden (20:80 Regel) und an diesen Stellen den Code performant zu bekommen.
Gruß
Markus