Nutzund der Forward declaration im header?
-
Ich hab eine header datei, die mit forward declarations arbeitet. in dieser header datei wird eine klasse mit einer pure virtual methode dklariert und ein paar zeilen später wird diese in der gleichen datei implementiert
Der Stil ist ungefähr:
// foo.h class FClass; class IMyClass { public: virtual void tuwas() = 0; }; template<class T> class MyClass : public IMyclass { public: virtual void tuwas(); }; #include "FClassImpl.h" template<class T> void MyClass::update() { for (std::vector<FClass*>::iterator it = obsList.begin(); it != obsList.end(); it++) { (*it)->update(); } }Die FclassImpl sieht so aus:
#include "foo.h" // <--- das Problem??? class FClass { public: virtual void update() = 0; }; // dann die konkrete klasse und implementation der update methodeDas kompiliert unter windows, aber make wirft mir folgendes an den
kopf:/Ma/foo.h: In member function ‘virtual void MyClass<T>::update()’:
/Ma/foo.h:117: error: invalid use of incomplete type ‘struct FClass’
/Ma/foo.h:45: error: forward declaration of ‘struct FClass’Mir ist auch nicht klar, warum er davon ausgeht, dass es ein struct und keine klasse ist.
Was kann hier das problem sein?
(Ich hab natürlich die vector deklaration usw weggelassen hier)
Ich include ja auch den header mit der definition und implementation und allem, daher müsste er doch zur kompilierzeit alles auflösen können
-
(*it)->update();Ist sowas wie:
FClass->update();Nun kennt er FClass aber nicht und weiss auch nicht, dass diese Klasse eine Methode update hat. Woher auch? Mit Forwarddeklarationen von Typen kann man nur arbeiten, falls man nur Zeiger oder Referenzen benutzt. Du hingegen rufst sogar Methoden auf. Abhilfe sollte ein Include des entsprechenden Headers von FClass schaffen. Zwar hast du die im Code angegeben, doch solltest du nochmal auf Gross- und Kleinschreibung achten.
-
Mir ist auch nicht klar, warum er davon ausgeht, dass es ein struct und keine klasse ist.
Ein
structist eine Klasse. Die Member sind einfach von Haus auspublic.Probier doch bitte den Code auf ein lauffähiges Beispiel runterzubrechen, bei dem der selbe Fehler geschieht. Ohne die genauen Implementierungen zu kennen wird es schwer..
@knivil:
Ich dachte auch, dass es das ist, allerdings scheint er die Implementierung ja zu inkludieren:#include "FClassImpl.h"Könnte theoretisch natürlich auch etwas anderes sein. Darum habe ich nochmal nachgefragt..
-
Ich habe es gesehen, aber ich dachte: Warum sollte in FClassImpl denn das Interface fuer FClass drin stehen, wenn FClass doch ein Interface und in FClassImpl dessen Implemetation sein soll (auch wuerde der Compiler dann nicht meckern).
Ach ja: Includeguards wirken manchmal Wunder.
-
Es gibt nen include guard, der verhindert, das diese sich gegenseitig ständig includen, daher irre ich mich wohl wegen der zirkulären referenz.
Ich muss mal gucken, was ich da machen kann.Ich versuch was zu bauen
-
Hmm. Da wurde ja ein paar mal bearbeitet. :p
Naja. Ich würde dir raten einmal das ganze so einfach wie möglich darzustellen. Ich habe irgendwie das Gefühl, dass du selber nicht so genau weisst, wie da die Abhängigkeiten sein sollen.

-
Hier ist kompilierbarer code:
// foo.h #ifndef foo #define foo #include <vector> class FClass; class IMyClass { public: virtual void tuwas() = 0; }; class MyClass : public IMyClass { public: virtual void tuwas(); std::vector<FClass*> obsList; }; #include "FClassImp.h" void MyClass::tuwas() { for (std::vector<FClass*>::iterator it = obsList.begin(); it != obsList.end(); it++) { (*it)->update(); } } #endif//FClassImp.h #ifndef FClassImpl #define FClassImpl #include "foo.h" class IFClass { public: virtual void update() = 0; }; class FClass : public IFClass { public: virtual void update() { // tu was } }; #endif//main.cpp #include <iostream> using namespace std; #include "FClassImp.h" #include "foo.h" int main() { MyClass m; cout << "Hello world!" << endl; return 0; }Das problem ist die include reihenfolge.
Nun ist es mir wenigstens klar, wo das problem ist. aber komisch, das visual studio das egal ist, und gcc nicht. nun ja, jetzt heißt es include suchen...
-
1.) Warum includierst du foo.h in FClassImpl.h?
2.) #include sollte meist am Anfang der Datei stehen, dann hat man einen besseren Ueberblick, was dieses Modul/Uebersetzungseinheit fuer Abhaengigkeiten hat. Auch faellt auf, dass du dann die Forwarddeklaration von FClass in foo.h nicht brauchst, da du sowieso das #include mit der kompletten Klassenbeschreibung spaeter benoetigst.