[Erledigt]#include "XYZ.h" Problem



  • Ich habe 2 Klassen, und in beiden befindet sich eine Instanz oder mindestens ein Zeiger von der jeweils andere, sodass ich in beiden Klassen die jeweils andere includen muss.
    Das führt aber zu unschönen compiler Fehlern.
    Ich habe eigentlich gedacht, dass

    #ifndef XYZ_H
    #define XYZ_H
    
    ....
    
    #endif
    

    das Ganze verhindert, aber anscheinend doch nicht. Was kann ich jetzt machen, oder was mache ich falsch?

    mfg



  • Versuch mal nachzuverfolgen was genau bei #include passiert...

    Ein Tipp für die Lösung: Forwärtsdeklaration & Forensuche.



  • Na ok, danke.
    Das Problem ist nur, wenn dir die Stichworte zum Suchen fehlen, kannst du auch nicht suchen.
    Ist ja nicht so, als würde ich den Thread sofort beim ersten Anzeichen eines Problems erstellen...

    mfg



  • So, neues Problem.

    So, vorhin habe ich die Klasse Z (hat einen Zeiger auf auf Klasse 😵 in Klasse X (erstellt Instanzen der Klasse Z) includiert und mit Vorwärtsdeklaration zum laufen gebracht.
    Nun kommt aber noch eine Klasse Y hinzu, die von Z erbt.
    So, nun includiere ich wie üblich Z in Y, doch ich erhalte einen tollen Fehler:

    error C2504: 'Z': Basisklasse undefiniert
    

    Wie kann ich da jetzt vorgehen? Ich hab alles mögliche ausprobiert, aber letztendlich nicht hinbekommen. Was jetzt wo vorwärtsdeklarieren, und wo includieren?

    Nochmal zur Verdeutlichung^^

    Basisklasse Z <---->  Eigenständige Klasse X
                ^
                |
    Beerbte Klasse Y
    

    mfg


  • Mod

    Zeig mal den Code. An sich sollte das nämlich keine Schwierigkeiten machen, deswegen nehme ich an, dass du was falsch machst.



  • Ok^^

    Das hier wäre die Klasse "Z":

    #ifndef GAMEOBJECT_H
    #define GAMEOBJECT_H
    
    #include <string>
    #include "TileMap.h"
    #include "Animation.h"
    
    class CTileMap;
    
    class CGameObject
    {
    ........
    ......
    };
    #endif
    

    und das die Klasse "X"

    #ifndef TILEMAP_H
    #define TILEMAP_H
    
    #include "Background.h"
    #include "Singleton.h"
    #include <map>
    #include "Animation.h"
    #include "GameAnimationObject.h"
    
    class CGameObject;
    
    class CTileMap : public TSingleton<CTileMap>
    {
    .....
    };
    #endif
    

    und das dann die Klasse Y die von Z erbt.

    #ifndef GAMEANIMATIONOBJECT_H
    #define GAMEANIMAIIONOBJECT_H
    
    #include "GameObject.h"
    
    class CGameAnimationObject : public CGameObject
    {
    ....
    };
    #endif
    


  • Hallo,

    rufe doch einfach mal den Preprozessor alleine auf und prüfe in welcher Reihenfolge die includes gelesen werden.

    mfg Martin



  • Und wie macht man sowas?^^
    Nutze VS 08



  • Hallo,

    völlig wurscht, in welcher Reihenfolge welches include gelesen wird.
    Wenn "GameObject.h" wirklich direkt vor der Klassendefinition inkludiert wird,
    dann sollte der Inhalt von GameObject auch bekannt sein.

    Prüfe nochmal:
    - Headerdatei richtig geschrieben?
    - Klassenname richtig geschrieben?
    - Bezieht sich der C2504-Fehler wirklich auf diese Zeile

    class CGameAnimationObject : public CGameObject
    

    ?



  • http://weseetips.com/2008/06/12/how-to-get-the-preprocessed-c-cpp-source-files/
    erster treffer bei google nach "visual studio präprozessor output"



  • Jockelx schrieb:

    Hallo,

    völlig wurscht, in welcher Reihenfolge welches include gelesen wird.
    Wenn "GameObject.h" wirklich direkt vor der Klassendefinition inkludiert wird,
    dann sollte der Inhalt von GameObject auch bekannt sein.

    Prüfe nochmal:
    - Headerdatei richtig geschrieben?
    - Klassenname richtig geschrieben?
    - Bezieht sich der C2504-Fehler wirklich auf diese Zeile

    class CGameAnimationObject : public CGameObject
    

    ?

    jupp, alles richtig,
    und ja, der Fehler ist in der Zeile, bzw in der Zeile unten drunter in der "{" steht.



  • Dann weiß ich's auch nicht. Letzte Möglichkeit die mir einfällt:

    Durchsuch dein Projekt mal nach

    #define GAMEOBJECT_H
    

    ob das vielleicht irgendwo anders schon definiert wird.


  • Administrator

    @Jockelx,
    Nein, es ist nicht "Wurst" in welcher Reihenfolge inkludiert wird.

    @anti-freak,
    Ist ein ganz typisches Problem:
    GameObject.h inkludiert TileMap.h
    TileMap.h inkludiert GameAnimationObject.h
    GameAnimationObject.h inkludiert GameObject.h ... oh moment, ist schon inkludiert, wir kommen ja von dort.
    Wir wollen GameAnimationObject von GameObject erben lassen, aber die Klasse GameObject wurde gar noch nicht deklariert oder definiert. Das wird erst nach allen Includes in GameObject.h der Fall sein. Fehler!

    Du hast hier Ringabhängigkeiten drin.

    Grüssli



  • Typisches Cross-Include-Problem!

    Entferne mal

    #include "TileMap.h"
    

    aus der Datei "GameObject.h".

    Und die TileMap benötigt sicherlich auch keine

    #include "Animation.h"
    #include "GameAnimationObject.h"
    

    Am besten, du zeichnest dir mal die Abhängigkeiten auf ein Blatt Papier auf - und dieses Diagramm sollte dann streng hierarchisch sein!



  • Egal wie ich es anstelle, letztendlich lande ich immer bei einem Compilerfehler.

    TileMap und MapObject brauchen sich gegenseitig.
    Die beerbte Klasse MapAnimationObject braucht MapObject, da es von dieser Klasse erbt und einen Zeiger, den es durch seine Basisklasse mitvererbt bekommt, aber aktiv in seinen Methoden nutzt.
    TileMap braucht dann letztendlich beide Klassen, weil beide für eine bestimmte Art Object auf der Map zuständig sind, das eine nur etwas spezifischer als das andere.

    Letztendlich würde sich daraus folgendes ergeben.

    #include "GameObject.h"
    #include "GameAnimationObject.h"
    
    class CTileMap : public TSingleton<CTileMap>
    

    für die TileMap Klasse

    #include "TileMap.h"
    
    class CGameObject
    

    für die GameObject Klasse

    #include "GameObject.h"
    #include "TileMap.h"
    
    class CGameAnimationObject : public CGameObject
    

    für die GameAnimationObject Klasse.

    Kürzt man nun die Header weg, die die einzelnen Klassen durch die bereits includeten Klassen mitbekommen, sähe das dann so aus.

    #include "GameAnimationObject.h"
    
    class CTileMap : public TSingleton<CTileMap>
    

    für die TileMap Klasse

    #include "TileMap.h"
    
    class CGameObject
    

    für die GameObject Klasse

    #include "GameObject.h"
    
    class CGameAnimationObject : public CGameObject
    

    Aber egal, welche der beiden Varianten, beide führen dazu, das der Compiler die Basisklasse "CGameObject" als nicht definiert ansieht.
    Also, ich bin mit meinem Latein am Ende....

    mfg



  • Ähm, und du verwendest die per Forward Declaration bekannt gemachten Klassen auch nur als Pointer in den Headern?



  • Ähm, Wie bitte?^^
    Wenn ich vorwärtsdeklaration einsetze, kommen die gleichen Fehler.



  • Th69 schrieb:

    Am besten, du zeichnest dir mal die Abhängigkeiten auf ein Blatt Papier auf - und dieses Diagramm sollte dann streng hierarchisch sein!

    Man kann sich das auch einfach als gerichteter Graph vorstellen mit den Datein als Knoten und den Pfeilen als Abhängigkeit (mit include). Dann darf einfach kein Zyklus enstehen (es muss ein poset := partially ordered set sein).

    @anti-freak:
    Ich empfehle dir mal das hier durchzulesen. Dann sollte es mit diesem Fehler ein für alle mal gegessen sein.

    //EDIT
    @Th69: Das war nicht als Belehrung gedacht, sondern als Alternative. Ich denke dir ist die Graphrepräsentation auch bewusst. 😉



  • Ey, dankeschön, das wusste ich ja gar nicht^^
    Wieder was gelernt 😛



  • anti-freak schrieb:

    Ey, dankeschön, das wusste ich ja gar nicht^^
    Wieder was gelernt 😛

    War es jetzt genau das?

    Hat sich wirklich gelohnt den Artikel zu schreiben. Verlink den bestimmt 1x/Woche. 🙂


Log in to reply