Basisklasse undefiniert
-
Hallo,
C++ und Includes ... Wer hat das bloß erfunden
Ich bekomme beim kompilieren immer folgende Fehlermeldung:
Kompilieren...
SearchStrategy.cpp
c:\vsdev\VividFormsReader\VividFormsReader*SearchFirst.h*(6) : error C2504: 'SearchStrategy': Basisklasse undefiniert
c:\vsdev\VividFormsReader\VividFormsReader*SearchFirst.h*(10) : error C2061: Syntaxfehler: Bezeichner 'SearchArea'Die Klassen sind folgendermaßen aufgebaut:
Klasse SearchArea:
#pragma once #include "comparablearea.h" #include "InvalidPositionException.h" #include <boost/shared_ptr.hpp> #include "searchfirst.h" class SearchStrategy; class SearchArea : public ComparableArea { public: SearchArea(int w, int h, int xCoordOrg, int yCoordOrg, unsigned char** searchArea, SearchStrategy *search); SearchArea(const SearchArea& rhs); virtual ~SearchArea(void); private: int width; int height; int xCoord; int yCoord; unsigned char **area; SearchStrategy* searchStrategy; public: int getWidth(void) const { return width; } int getHeight(void) const { return height; } int getXCoord(void) const { return xCoord; } int getYCoord(void) const { return yCoord; } int getPixel(int xCoord, int yCoord) const; SearchArea& operator=(const SearchArea& rhs); static boost::shared_ptr<SearchArea> Create(const CEPPosition& pos, const CEPGraphics2D& graphic); protected: void cleanArea(void); };Klasse SearchStrategy:
#pragma once #include "searchresult.h" #include "pattern.h" #include "searcharea.h" class SearchArea; class SearchStrategy { public: SearchStrategy(void); virtual ~SearchStrategy(void); virtual SearchResult search(SearchArea* searchArea, Pattern* pattern) const = 0; };Klasse SearchFirst:
#pragma once #include "searchstrategy.h" class SearchFirst : public SearchStrategy { public: SearchFirst(void); virtual ~SearchFirst(void); SearchResult search(SearchArea* searchArea, Pattern* pattern) const; };Wer kann mir helfen den Include-WirrWarr zu entfädeln?
Danke im voraus!!!
Gruß,
Chris
-
Die drei Header bilden einen Include-Kreis: SearchFirst -> SearchStrategy -> SearchArea -> SearchFirst.
Die einzige Direktive, die du wirklich brauchst, ist die von searchstrategy.h in SearchFirst, denn da geht es um eine Basisklasse. Die anderen kannst du einfach in die dazugehörigen .cpp-Dateien verschieben, die Vorwärtsdeklarationen hast du ja schon.
-
Danke MFK! So funktioniert es...
Ich muss mir doch noch einmal die ganze Include-Geschichte verdeutlichen... Hast Du dazu zufällig einen guten Link parat?
-
so viel gibst da doch eigentlich nicht zu sagen:
Wir haben "#include" ja bereits kennengelernt - doch was macht der Präprozessor da genau? Er macht eine einfache Textersetzung. Er kopiert den ganzen Inhalt der zu includenden Datei an die Stelle wo das #include steht. Bei #include "foo" sucht der Präprozessor im aktuellen Verzeichnis nach foo und bei #include <foo> sucht er im Include-Verzeichnis des Compilers.
-

Den Satz verstehe ich schon, aber die Einfachheit wird in komplexen Programmen (zumindest was mich betrifft) ziemlich Unübersichtlich.In anderen Programmiersprachen wie Java ist der Sachverhalt in meinen Augen verständlicher. Das liegt wohl vor allem daran, das man nicht unterscheiden muss wann man den Include in die h-Datei und wann in die cpp-Datei setzten muss...
Vielleicht fehlt mir auch einfach die Erfahrung ^^

-
achso^^
naja ich inkludier immer alle header dateien in meiner *.h datei dann kann nämlich meine *.h und meine *.cpp datei die funktionen der header datei benutzen weil ich in meiner *.cpp ja auch meine *.h datei inkludier.verstehst du den satz auch schon?^^
wenn nein dann weiss ich fast auch nicht weiter
-
Hallo
und genau das ist der Grund für dein Problem gewesen.
Du solltest immer so wenig wie nötig includen, vor allem in Headern selber. Auch mit Forward Declaration kann man sich machen Include sparen.
Das hilft einerseits die Kompilierzeit zu senken, anderseits auch solche Kreis-Includes zu vermeiden.bis bald
akari
-
heisst das ich hab recht?
-
Also Fachmann ich glaube du solltest nicht alle Dateien in deine *.h Datei includieren ^^ Genau das habe ich ja auch gemacht...

Frage mich gerade warum ich nicht gleich auf Scott Meyers gehört habe?
Item 31: Minimize compilation dependencies between files.
* Depend on class declarations instead of class definitions whenever you can.Includiert Ihr generell (die Ihr mehr Erfahrung habt als ich) keine (eigene) Header-Files (in *.h) sondern deklariert nur die Klasse? Kann man das generalisieren, oder gibt es Ausnahmen?
Gruß,
Chris
-
Hallo
Includiert Ihr generell (die Ihr mehr Erfahrung habt als ich) keine (eigene) Header-Files (in *.h) sondern deklariert nur die Klasse? Kann man das generalisieren, oder gibt es Ausnahmen?
Es gibt immer Ausnahmen. Die Forward Deklaration reicht wenn man nur einen Pointer oder Referenz braucht. Braucht man aber konkrete Instanzen oder will man von der Klasse ableiten, muß man die gesamte Deklaration kennen. Dann kommt man um einen Include im Header nicht umhin.
bis bald
akari
-
Danke Akari,
klingt ziemlich logisch und macht Sinn. Gibt der scheinbar einfachen Definition des Includes aber einen faden Beigeschmack, weil der unerfahrene C++Coder durch einen Includekreis schnell mal in die Tischkannte beisst ...
Ok, wie gesagt danke für die Einsichten!

-
HolyGrail schrieb:
...Gibt der scheinbar einfachen Definition des Includes aber einen faden Beigeschmack, ...
Naja, ich finde, es zwingt einen eben dazu, sich exakter Gedanken über Abhängigkeiten zu machen.
... und wenn man seine Abhängigkeiten nicht sauber in den Griff bekommt, beissen einen die viel später (und oft unangenehmer) ins Gesäß.
Gruß,
Simon2.
-
Gedanken die ein Programmierer (meiner Meinung nach), aber besser in sein Softwaredesign stecken sollten, als in solche "Sprachdetails".
--- Will jetzt aber keine Grundsatzdiskussion auslösen

-
HolyGrail schrieb:
Gedanken die ein Programmierer (meiner Meinung nach), aber besser in sein Softwaredesign stecken sollten, als in solche "Sprachdetails"....
Wenn er zu dem "Sprachdetail" kommt, ist aber die Designphase eigentlich schon vorbei - d.h. er tappt in die Falle, die er sich vorher selbst gelegt hat.
Hat er eine saubere Abhängigkeitsdefinition designed, fällt ihm das include nicht in den Arm....
... ich weiß, dass das "Schönwetterflugtheorie" ist.

Gruß,
Simon2.
-
Hi,
ich hätte zu dem Thema auch noch ne Frage:
http://www.sambalmueslie.de/test/Klassendiagramm.png
So sieht meine Struktur aus.Jetzt steh ich vor dem Problem:
- Was wo includen?
- Wo eine Forward Deklaration
Da die Klasse Framework alle anderen Klassen verwendet ist es da wohl eher sinnvol diese zu includen oder?
In der Klasse Handler hab ich eine Forward-Deklaration auf Framework.
#ifndef HANDLER_H_ #define HANDLER_H_ #include <iostream> using namespace std; #include "Object.h" #include "Framework.h" #include "HandlerInfo.h" #include "MSTEvent.h" #include "MSTMessage.h" //#define HANDLER_DEBUG 0 class Framework; extern Framework *the_framework; class Handler : public Object { public: Handler(); Handler(Handler & rhs); ~Handler(); HandlerInfo& getHandlerInfo(); int getHandlerStatus(); virtual void reciveEvent(MSTEvent* event); virtual void sendEvent(MSTEvent* event); virtual void sendMessage(MSTMessage* message); virtual void output(ostream& os); virtual void operator=(Handler & rhs); friend ostream& operator << (ostream& os, Handler& op); private: int handler_id; int handler_status; HandlerInfo handler_info; }; #endif /*HANDLER_H_*/jetzt meckert mir halt der Compiler bei
void Handler::sendMessage(MSTMessage * message) { #ifdef HANDLER_DEBUG cout << __PRETTY_FUNCTION__ << endl; #endif the_framework->writeMessage(message); }no matching function for call to ‘Framework::writeMessage(MSTMessage*&)’ MCX_Software_Test_V_0_4_1/MST_Framework/Handler Handler.cpp line 60
Was mir auch logisch erscheint.
Doch wie bekomme ich das weg??Grüßle Oli
-
Wie gesagt, inkludiere so wenig wie nötig.
D.h. entferne erst mal alle Includes und ersetze sie durch Vorwärtsreferenzen...
(außer "object.h", da du ja davon ableitest sowie "HandlerInfo.h", da du davon ein Member erzeugst)Selbst <iostream> kannst du durch <iosfwd> ersetzen (Forward references).
Nur in den Source-Dateien brauchst du dann die includes...
und vor allem:
Verwende NIEMALS "using namespace std;" in Header-Dateien!!!
-
Th schrieb:
Wie gesagt, inkludiere so wenig wie nötig.
D.h. entferne erst mal alle Includes und ersetze sie durch Vorwärtsreferenzen...
(außer "object.h", da du ja davon ableitest sowie "HandlerInfo.h", da du davon ein Member erzeugst)Selbst <iostream> kannst du durch <iosfwd> ersetzen (Forward references).
Nur in den Source-Dateien brauchst du dann die includes...
und vor allem:
Verwende NIEMALS "using namespace std;" in Header-Dateien!!!Oki ich versuchs mal, kleine Frage am Rande noch, was sind den Vorwärtsreferenzen??
Grüßle Oli
-
class Framework; // Vorwärtsreferenz (Forward Reference)
-
Th schrieb:
class Framework; // Vorwärtsreferenz (Forward Reference)Ah ok.. thx..
-
ich halte es immer so, dass es eine zentrale headerfile gibt in der alle anderen header included werden. alle .cpp-dateien inkludieren *ausschließlich* diesen header.
header-files (mit ausnahme des zentralen) inkludieren in diesem modell in der regel keine anderen header.dadruch werden alle cpp-dateien von allen headern abhängig. jede header-änderung führt deshalb dazu, dass alle files neu kompiliert werden müssen. allerdings hat das auch einen großen vorteil: visual c++ kann precompiled header nur so mit maximaler effizienz verwenden, was die kompilierungsgeschwindigkeit teilweise enorm steigert.
ich hab früher auch immer darauf geachtet, abhängigkeiten wo immer möglich zu vermeiden. im endeffekt bringts aber nix ausser zusätzlicher arbeit. die precompiled header machen die zusätzlichen abhängkeiten eigentlich immer mehr als wett.
ein projekt, umgestellt auf dieses modell, kompilierte nachher mehr als 10 mal so schnell.
-
HolyGrail schrieb:
Includiert Ihr generell (die Ihr mehr Erfahrung habt als ich) keine (eigene) Header-Files (in *.h) sondern deklariert nur die Klasse? Kann man das generalisieren, oder gibt es Ausnahmen?
Kurz gesprochen: Includiere was nötig ist, Deklariere was möglich ist

Sofern ich Includes vermeiden kann, mache ich das auch (Sprich sofern nur Pointer oder Referenzen im Header verwendet werden: Vorwärtsdeklaration; sonst include). Dies hat mehrere Vorteile, einer davon ist die reduzierte Compilezeit

cu André