Gegenseitiges includen von Klassen



  • Ich bräuchte eure Hilfe.

    In meinem Projekt habe ich Klassen die gegenseitig voneinander abhängig sind.
    Vermutung: Wenn ich eine Klasse (Header) einbinde, setze ich ja den Schalter (Include-Guard) im Projekt damit es zu keiner Mehrfachdeklaration kommt.

    Wie kann ich vorgehen?

    Die Headerdateien binde ich in jede Klasse mit einem Includes-Header ein

    #include "xyz.h"
    #include "zyx.h"
    #include "yzx.h"
    #include "xzy.h"
    //...
    

    Ohne Include-Guard.
    Gibt es eine Möglichkeit mit dem Preprocessor ein Output zu machen?
    #Ausgeben "Wurde eingebunden"

    ?

    Danke im voraus!



  • Hmm mit den Output weiss ich nicht genau obs da was gibt. Aber Mehrfachincludes lassen sich einfach lösen: Visual C++ ermöglicht ein

    #pragma once
    

    alternativ kann man das mit einen define lösen

    #ifndef MY_HEADER_H
    #define MY_HEADER_H
    ..
    class MyClass
    {...
    
    }
    #endif
    

    Dabei musst du natürlich MY_HEADER_H für jeden Header anders benennen.



  • a) keine Defines niemals nicht mit einem _ beginnen
    b) niemals nicht gar nicht auf keinen Fall Defines mit doppelten _ verwenden



  • Habs geändert. Mich würde das Warum aber mal interessieren.



  • Anscheinend ist mein Problem falsch rübergekommen...

    -) Ich hab mehrere Klassen die gegenseitig voneinander abhängig sind. Jede Klasse hat einen INCLUDE-GUARD !
    -) Die Klassen binde ich alle mit einem Include-Header ein, damit ich nicht immer so einen großen Haufen einbinden muss. Der Include-Header schaut so aus:

    #include "xyz.h"
    #include "zyx.h"
    #include "yzx.h"
    #include "xzy.h"
    //...
    

    Die Fehler: In vielen Klassen sind die anderen Klassen unbekannt. "class xyz has not been declared..." usw

    Vermutung: Wenn ich eine Klasse einbinde setze ich ja den Include-Guard auf true ( abstrakte Vorstellung ), damit ich sie ja nicht mehrfach deklariere. Aber ich muss doch die Klasse auch in den anderen Klassen includieren.

    Hoffe das war verständlicher.

    Danke für eure Antworten.

    Fedaykin schrieb:

    Habs geändert. Mich würde das Warum aber mal interessieren.

    Weil es sein kann, dass diese vom Compiler besetzt sind.



  • Das Inkludieren funktioniert so nicht. Du darfst in den Headern die jeweiligen anderen Header nicht unkludieren. Stattdessen besnutze Forward Declarations

    // statt #include "xyz.h": (wenn die Klasse denn xyz heißt)
    class xyz;
    

    und inkludiere die jeweiligen Header dann in den Source-Files. Allerdings kannst du in den jeweiligen Headern nur mit Pointern/Referenzen auf die anderen Klassen arbeiten.

    @ Fedaykin
    Weil die reserviert sind, vom Compiler, dem Standard, Whatever. Ist zwar nicht sonderlich wahrscheinlich daß man eben einen solchen per Zufall erwischt (was zu nervigen Problemen führt), dennoch sollte es vermieden werden.



  • Fellhuhn schrieb:

    und inkludiere die jeweiligen Header dann in den Source-Files. Allerdings kannst du in den jeweiligen Headern nur mit Pointern/Referenzen auf die anderen Klassen arbeiten.

    hmmpf, kannst du mir auch sagen wieso? 😞



  • fragensteller_small_3. schrieb:

    hmmpf, kannst du mir auch sagen wieso? 😞

    Zu 1) Schau dir an was der Präprozessor aus den gegenseitigen Includes macht und ob er das lösen kann.
    2) Wenn du auf dem Stack ein Objekt ablegen willst, muss der Compiler wissen wie groß das Objekt sein wird. Dafür muss bekannt sein, welche Member der hat, welche Typen das sind, usw. Und das geht nunmal nicht ohne der Klassendefinition - die steh im Header und nicht in ner Forwarddeklaration 😛



  • Naja, das stimmt so nicht. Nach Klassendeklarationen kann man diese in Funktionsköpfen "normal" verwenden. IIRC erlauben manche Compiler auch eine Verwendung als Template-Parameter. Wenn man wirklich einen Klassenmember von diesem deklarierten Typ braucht (und es nicht über Smart Pointer etc. lösen kann), kann man das Pimpl-Idiom anwenden.

    Lies dir am besten mal http://www.gotw.ca/gotw/007.htm durch.



  • fragensteller_small schrieb:

    In meinem Projekt habe ich Klassen die gegenseitig voneinander abhängig sind.

    Ok.

    fragensteller_small schrieb:

    Vermutung: Wenn ich eine Klasse (Header) einbinde, setze ich ja den Schalter (Include-Guard) im Projekt damit es zu keiner Mehrfachdeklaration kommt.

    Stopp mal. Deklarieren kannst Du so oft, Du willst. Eine Klasse darf allerdings nur einmal pro Übersetzungseinheit definiert werden. Das wird typischerweise durch Include-Guards verhindert, ja.

    fragensteller_small schrieb:

    Wie kann ich vorgehen?

    Du hast bisher nicht viel verraten, was wo wie genau voneinander abhängt. Ich würde erstmal sagen, es klingt komisch, dass Du 4 (?) Klassen, die sich alle gegenseitig bedingen, in mehrere Header/ÜEs aufteilen willst. Mach's doch mal konkreter. Nenne uns die Klassen und sage welche Klassendefinitionen (das ist das mit den geschweiften Klammern) welche anderen Klassen benennen und wie genau.

    Hier nochmal zum Abschreiben:

    class Foo;    // <-- Deklaration
    class Foo{};  // <-- Definition
    

Log in to reply