Wann Quellcode einer Funktion in die Header-Datei (und warum)
-
Hallo,
warum muss in bestimmten Situation der Quellcode einer Klassenfunktion in die Header Datei geschrieben werden? Beispiel,Foo.h(pp):
class Foo { public: FooB* TueEtwas(char* msg); Foo(); ~Foo(); };Foo.cpp:
#include "Foo.h(pp)" FooB* Foo::TueEtwas(char* msg) { ... return new FooB(); } Foo::Foo(){} Foo::~Foo(){}In bestimmten fällen, liefert mir der Compiler beim Linken "Undefined Reference to Foo::TueEtwas in BlaBla".
Wenn ich den selben Quellcode aber direkt in die Header-Datei der jeweiligen Funktion schreibe funktioniert es. Gibt es eine Richtlinie wann ich das in den Header schreiben muss und wann nicht?
-
Bei Templates (ausser der Kompiler unterstützt export).
Ansonsten nicht und sollte meines erachtens immer getrennt in *.h und *.cpp werden. (Der Kompiler macht das inlining sowiso besser als der Programmierer.)Simon
-
Das mit den Templates ist mir mittlerweile bekannt.
Die Klasse wo das Problem auftrat ist allerdings keine Template-Klasse. Die Basisklasse von FooB ist allerdings eine Basisklasse gewesen. Hängt das damit zusammen?
Und warum können in Templates die Funktionsrümpfe nicht getrennt von den Quellcodedateien abgelegt werden?
-
Kann schon, dann musst du aber die Ausprägungen mit angeben und kannst auch keine anderen als die Angegeben verwenden. Der Grund: Beim separaten Kompilieren kann der Compiler ja nicht wissen welche Ausprägungen benötigt werden.
-
kleines_eichhoernchen schrieb:
Das mit den Templates ist mir mittlerweile bekannt.
Die Klasse wo das Problem auftrat ist allerdings keine Template-Klasse.
Dann hängt es höchstwahrscheinlich damit zusammen, dass die Quellcodedatei, die die fehlende Funktion beinhaltet nicht mit der, die main beinhaltet zusammen gelinkt wurde.
-
LordJaxom schrieb:
Dann hängt es höchstwahrscheinlich damit zusammen, dass die Quellcodedatei, die die fehlende Funktion beinhaltet nicht mit der, die main beinhaltet zusammen gelinkt wurde.
Doch doch, die ist dabei.
@Tyrdal
für unwissende, was sind Ausprägungen? Die einzelnen Template-Argumente bei den Templates selbst?
-
Der Compiler dröselt die Templates auf zu konkreten Klassen/Methoden, je nachdem mit welchen Typen du sie verwendest.
-
Aso OK,
(das ist ja blöd vom Compiler, dass das nicht zur Laufzeit geschieht). Na gut das zur Laufzeit wär auch nicht so berauschend. Aber gut. Danke, jetzt weiß ich bescheid.
-
kleines_eichhoernchen schrieb:
In bestimmten fällen, liefert mir der Compiler beim Linken "Undefined Reference to Foo::TueEtwas in BlaBla".
ja, (wie gesagt), immer dann, wenn foo.cpp (bzw. die fertig-kompilierte übersetzungseinheit) nicht mit dem rest deines programms verlinkt wird. ersetze mal "BlaBla" durch das, was der linker dir tatsächlich sagt.
-
kleines_eichhoernchen schrieb:
...(das ist ja blöd vom Compiler, dass das nicht zur Laufzeit geschieht)...
Das was du als Nachteil ansiehst ist aber ebenso ein gewaltiger Vorteil.
Ich bezweifel das sonst die Templatemetaprogrammierung funktionieren würde, und mir persönlich wichtiger: Ich möchte das der Compiler möglichst viele Fehler findet, und diese nicht erst zur Laufzeit auftreten.cu André
-
So hatte das selbe Problem nochmal.
foo.hpp:class Foo { public: void SomeFunc(); ... void SomeFunc2(struct soap *soap, ...); Foo(); ~Foo(); };foo.cpp
#include "foo.hpp" void Foo::SomeFunc() {...} void Foo::SomeFunc2(struct soap *soap, ...) {...} Foo::Foo() {...} Foo::~Foo() {...}bar.cpp
#include "bar.hpp"; #include "foo.hpp"; void SomeFunc3() { Foo foo; struct soap soap; foo.SomeFunc2(&soap, ...); }Die beiden cpp-Dateien ließen sich wunderbar kompilieren. Beim Linken trat allerdings
*undefined reference to Function "Foo::SomeFunc2(struct soap soap, ...)" in File bar.o (bar.cpp)
Nach längerem probieren bin ich dann dadrauf gekommen, dass der Compiler/Linker das struct soap nicht kennt, bzw. kennen kann, da auf die Header-Datei nicht verwiesen wurde/konnte. Mit der Änderung
foo.hpp:
struct soap; class Foo { ... };hat es dann funktioniert. Allerdings ist die Compilermeldung/Linkermeldung sehr irreführend. Mit der Implementierung der Funktion Somefunc2() in der Header-Datei selbst funktioniert es auch ohne Forward-Deklaration!????