include wirrwar
- 
					
					
					
					
 Hallo, Mein Projekt wird langsam ziemlich gross und ich bekomme immer öfter die 
 Meldung "multiple definition of `enum xxx' " etc....Bislang behelfe ich mir damit, das ich bei den betreffenden Headern einfüge: #ifndef _MY_HEADER_H_ #define _MY_HEADER_H_ #endifUnd in den betreffenden cpp files #ifndef _MY_HEADER_H_ #include "MyHeader.h" #endifMeine Frage nun: Gibt es irgendein Tool, das diese Abhängigkeiten (bzw. Ringverweise) irgendwie auflöst und meldet bzw. bereinigt ? Zwar gehts auch mit der oben skizzierten Methode, jedoch will ich eigentlich vermeiden, zig Zeilen Präprozessorcode vor dem eigentlichen c++ code zu schreiben. 
 
- 
					
					
					
					
 yusha schrieb: Und in den betreffenden cpp files #ifndef _MY_HEADER_H_ #include "MyHeader.h" #endifDas bringt nichts, jedenfalls nichts, was die Includeguards in den Headern nicht auch tun würden. Weg damit. 
 
- 
					
					
					
					
 Was sind "include guards" ?  
 
- 
					
					
					
					
 yusha schrieb: Was sind "include guards" ?  Include guards werden die folgenden Präprozessor-Direktiven genannt. #ifndef MY_SPECIAL_HEADER_HPP #define MY_SPECIAL_HEADER_HPP // Deklarationen ... #endif // MY_SPECIAL_HEADER_HPPDiese Guards sind im Prinzip nichts weiter als eine "Präprozessor-if-Anweisung". Sie verhindern, dass innerhalb einer Übersetzungseinheit mehrmals der gleiche Header inkludiert wird. (Wenn der Bezeichner MY_SPECIAL_HEADER_HPP noch nicht definiert wurde, dann definiere ihn und inkludiere die entsprechenden Deklarationen, etc.... wenn versucht wird den gleichen Header erneut zu inkludieren ist MY_SPECIAL_HEADER_HPP bereits definiert, weshalb der Header nicht erneut inkludiert wird)... 
 
- 
					
					
					
					
 yusha schrieb: Was sind "include guards" ?  Das: yusha schrieb: #ifndef _MY_HEADER_H_ #define _MY_HEADER_H_ #endif(Wenn das #endif am Ende der Datei steht) 
 
- 
					
					
					
					
 Oh wow, vielen Dank für die schnelle Hilfe. Ist ja fast Echtzeit hier im Forum  also in zukuft sollten die headerfiles so aussehen, ja ? #ifndef _MY_HEADER_H_ #define _MY_HEADER_H_ . // die definitionen . . #endif
 
- 
					
					
					
					
 versuche es mal mit namespaces. namespace A { size_t dasDickeI = 5; } namespace B { size_t dasDickeI = 1; } // millionen zeilen code später // die funktion sollte eigentlich auch in einem namespace stehen void func() { std::cout << "A: " << A::dasDickeI << '\n'; std::cout << "B: " << B::dasDickeI << '\n'; }mfg 
 
- 
					
					
					
					
 Namespaces ändern auch nichts an der Tatsache, dass eine Definition mehrfach in einer Übersetzungseinheit auftaucht. Include-guards sind da die einzige Lösung. 
 
- 
					
					
					
					
 User-- schrieb: Namespaces ändern auch nichts an der Tatsache, dass eine Definition mehrfach in einer Übersetzungseinheit auftaucht. Include-guards sind da die einzige Lösung. er hatte doch schon welche. Bislang behelfe ich mir damit, das ich bei den betreffenden Headern einfüge: #ifndef _MY_HEADER_H_ #define _MY_HEADER_H_ #endifmfg 
 
- 
					
					
					
					
 dem anschein nach hat er aber alle drei zeilen an den anfang seines headers geschrieben, also nur um sein _MY_HEADER_H_ zu defnieren (im übrigen sind afaik namen mit unterstrich und capital danach reserviert, nur mal so am Rande). 
 Wenn er richtige includeguards (#endif in der allerletzten Zeile der Headerdatei) in allen headern anwendet, sollte das Problem verschwinden.
 
- 
					
					
					
					
 terraner schrieb: User-- schrieb: Namespaces ändern auch nichts an der Tatsache, dass eine Definition mehrfach in einer Übersetzungseinheit auftaucht. Include-guards sind da die einzige Lösung. er hatte doch schon welche. Bislang behelfe ich mir damit, das ich bei den betreffenden Headern einfüge: #ifndef _MY_HEADER_H_ #define _MY_HEADER_H_ #endifmfg Wenn ich ihn richtig verstanden habe, hat er überall dort include-guards eingefügt wo das Problem bestand und es damit behoben, nur wusste er noch nicht, dass man die eben braucht und nicht nen billiger Hack sind (na gut eigentlich sind sie nen billiger hack). 
 
- 
					
					
					
					
 ich hab ein ähnliches prob. ich benutze visual c++ 6. gegeben sind zwei klassen "meineKlasseA" und "meineKlasseB" der art: meineKlasseA: // meineKlasseA.h: Schnittstelle für die Klasse meineKlasseA. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MEINEKLASSEA_H__63D8C0C4_4DE5_4EB9_9F6F_D66FC4504556__INCLUDED_) #define AFX_MEINEKLASSEA_H__63D8C0C4_4DE5_4EB9_9F6F_D66FC4504556__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "meineKlasseB.h" class meineKlasseA { public: meineKlasseA(); virtual ~meineKlasseA(); private: meineKlasseB* m_mkB; }; #endif // !defined(AFX_MEINEKLASSEA_H__63D8C0C4_4DE5_4EB9_9F6F_D66FC4504556__INCLUDED_) // meineKlasseA.cpp: Implementierung der Klasse meineKlasseA. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "stdafx.h" #include "meineKlasseA.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Konstruktion/Destruktion ////////////////////////////////////////////////////////////////////// meineKlasseA::meineKlasseA(){} meineKlasseA::~meineKlasseA(){}meineKlasseB: // meineKlasseB.h: Schnittstelle für die Klasse meineKlasseB. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MEINEKLASSEB_H__3BAFBBE1_2480_4C06_90C1_57395654F84E__INCLUDED_) #define AFX_MEINEKLASSEB_H__3BAFBBE1_2480_4C06_90C1_57395654F84E__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "meineKlasseA.h" class meineKlasseB { public: meineKlasseB(); virtual ~meineKlasseB(); meineKlasseA* m_mkA; }; #endif // !defined(AFX_MEINEKLASSEB_H__3BAFBBE1_2480_4C06_90C1_57395654F84E__INCLUDED_) // meineKlasseB.cpp: Implementierung der Klasse meineKlasseB. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "stdafx.h" #include "meineKlasseB.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Konstruktion/Destruktion ////////////////////////////////////////////////////////////////////// meineKlasseB::meineKlasseB(){} meineKlasseB::~meineKlasseB(){}also kurz gesagt: in der ersten klasse brauche ich objekte von der zweiten klasse und in der zweiten brauche ich die objekte von der ersten klasse, die klassen sind also "quer-included". 
 Dabei bekomme ich folgende Fehlermeldungen:--------------------Konfiguration: HTTPrequest - Win32 Debug-------------------- 
 Kompilierung läuft...
 meineKlasseA.cpp
 i:\cplusplus\httprequest\meineklasseb.h(20) : error C2143: Syntaxfehler : Fehlendes ';' vor ''
 i:\cplusplus\httprequest\meineklasseb.h(20) : error C2501: 'meineKlasseA' : Fehlende Speicherklasse oder Typbezeichner
 i:\cplusplus\httprequest\meineklasseb.h(20) : error C2501: 'm_mkA' : Fehlende Speicherklasse oder Typbezeichner
 Generieren von Code...
 Kompilieren...
 meineKlasseB.cpp
 i:\cplusplus\httprequest\meineklassea.h(21) : error C2143: Syntaxfehler : Fehlendes ';' vor ''
 i:\cplusplus\httprequest\meineklassea.h(21) : error C2501: 'meineKlasseB' : Fehlende Speicherklasse oder Typbezeichner
 i:\cplusplus\httprequest\meineklassea.h(21) : error C2501: 'm_mkB' : Fehlende Speicherklasse oder Typbezeichner
 Generieren von Code...
 Fehler beim Ausführen von cl.exe.
 Browse-Informationsdatei wird erstellt...HTTPrequest.exe - 6 Fehler, 0 Warnung(en) Wie kann man sowas umgehen? Sorry, wenn es zu lang geworden ist. 
 
- 
					
					
					
					
 erstmal: nette defines, prädestiniert für Tippfehler  dann: dein #if !defined(...)ist etwas ungewohnt, ich kenne das als einfaches #ifndef #define new DEBUG_NEW 
 das definiert in meinen augen das wörtchen "new" als synonym für "DEBUG_NEW", sprich, wenn der Präpro irgendwo ein "new" findet, ersetzt ers mit "DEBUG_NEW". Was natürlich gewollt sein kann, ich weiß ja nicht, was du mit deinen ganzen Präpro-anweisungen zaubern möchtest.Schlussendlich: du includierst in beiden headern den jeweils anderen, obwohl du die Klassendefinition garnicht brauchst - eine Deklaration reicht da völlig: ersetze in den *.h dateien mal das #include meineklasseB.hdurch eine einfache Deklaration: class meineklasseB;denn der Compiler braucht zu dem zeitpunkt nicht mehr zu wissen, als dass es diese Klasse gibt. 
 
- 
					
					
					
					
 ich bin "neu" in diesem Forum und muss staunen, dass es wirklich schnell ging, vielen dank, das hat jetzt auf jeden fall im test-proggie geklappt, was mich natürlich freut.  zu erstmal: nette defines, prädestiniert für Tippfehler  sowas macht MS Visual C++6 standardmäßig, wenn man per menü->einfügen->neue klasse... eine neue klasse erstellt, und in der doku wird empfolen die finger davon weg zu nehmen, denn anhand solcher Code-Zeilen weiß der "KlassenAssistent", wo er was automatisch einfügen soll. DEBUG_NEW - Makro ist auch gewollt, es soll dem entwickler beim memory-leaks-suchen helfen. Gibt es eine einfache erklärung dafür, dass es beim quer-verincluden nicht klappte?? 
 Danke nochmals
 
- 
					
					
					
					
 Ich kenn mich mit VC6 nicht aus (und nach dem was ich in letzter Zeit so an Eigenheiten höre will ich das auch garnicht), aber es sieht so aus, als ob er trotz der includes die jeweils andere KLasse nicht kannte. (Deshalb wollte er in meineklasseB.h z.B. das Semicolon nach "MeineKlasseA". Und unter dieser Annahme konnte er natürlich mit den einfachen Bezeichnern "MeineKlasseA" und "m_mkA" nichts anfangen. Ist aber nur ne Vermutung.. 
 
- 
					
					
					
					
 Die includes werden ja in der angebenen Reihenfolge abgearbeitet. 
 Angenommen es wird gerade die MeineKlasseA abgearbeitet. Dort wird, ziemlich weit oben, #include "MeineKlasseB.h" gefunden, also wird diese nun abgearbeitet. Dort wird dann wieder MeineKlasseA verwendet. Diese kennt er aber noch nicht, weil er noch nicht bit zu dem Schlüsselwort class in MeineKlasseA gekommen ist. Ein Teufelskreis. 
 
- 
					
					
					
					
 ja, logisch  , danke schön! Ich begegnete diesem Problem schon desöfteren bei der Entwicklung eines mittelgroßen Projektes. Nur konnte ich es dort nicht so elegant lösen, wie ich es jetzt könnte. Vielen Dank , danke schön! Ich begegnete diesem Problem schon desöfteren bei der Entwicklung eines mittelgroßen Projektes. Nur konnte ich es dort nicht so elegant lösen, wie ich es jetzt könnte. Vielen Dank