invalid use of undifined type



  • Hallo zusammen,
    ich sitze seit gestern vor einem Problem...
    Ich versuche eine Klasse zu vererben doch beim Compilieren stoppt es bei dem oben genannten Fehler. An der Stelle an der die Definition der Child-Klasse beginnt.
    Aus irgeneinem Grund findet bzw. will er meine Parent-Klasse nicht. Ich habe die Header-Datei der Parent-Klasse in der Child-Klasse includiert und zusätzlich im Header der Child-Klasse eine forward declaration der Parent-Klasse eingefügt.
    Ich hab jetzt schon viel versucht um den Fehler einzugrenzen. Zum Beispiel kann ich, wenn ich die Vererbung weg lasse in der Child-Klasse einen Zeiger auf die Parent Klasse deklarieren allerdings kein Objekt?!
    Das zweit was ich versucht habe ist. Ich habe direkt über die Klassen Definition im Child-Header eine "Dummy"-Klasse erstellt und die dann vererbt. Das funktioniert dann auch?! Ich bin mit meinem Latein am Ende 😕

    Ich hoffe ihr könnt mir helfen!!

    MfG



  • _c0mpiler schrieb:

    Ich habe die Header-Datei der Parent-Klasse in der Child-Klasse includiert und zusätzlich im Header der Child-Klasse eine forward declaration der Parent-Klasse eingefügt.

    Letzteres sollte gar nicht notwendig sein, wenn du eine Includedirektive für den Parent-header hast.

    Du hast nicht zufällig auch im Parent-Header eine Includedirektive für den Child-Header?



  • Nein ich hab In der Parent-Klasse keine Child Klasse includiert. Und wenn fang ich solche Fehler mit Präprozessor Direktiven ab. Die forward declaration mach ich zwecks eines anderen Fehlers. Wird diese weggelassen erhalt ich die Fehlermeldung in der Child-KLasse, dass der Name meiner Parent-KLasse bei der Vererbung undefiniert ist bzw. er erwartet vor '{' einen Klassennamen.

    MfG



  • _c0mpiler schrieb:

    Nein ich hab In der Parent-Klasse keine Child Klasse includiert. Und wenn fang ich solche Fehler mit Präprozessor Direktiven ab.

    Du kannst zyklische Includedirektiven nicht mit Include-Guards "abfangen", falls es das ist, was du meinst.

    _c0mpiler schrieb:

    Die forward declaration mach ich zwecks eines anderen Fehlers. Wird diese weggelassen erhalt ich die Fehlermeldung in der Child-KLasse, dass der Name meiner Parent-KLasse bei der Vererbung undefiniert ist bzw. er erwartet vor '{' einen Klassennamen.

    Wie gesagt, wenn deine Includes in Ordnug wären, bräuchtest du keine Forward Declaration, d.h. dieser Fehler würde gar nicht auftreten.

    Stell sicher, dass der Child-Header nicht in den Parent-Header eingebunden wird, auch nicht indirekt.



  • Also abgesehen davon, dass Code hier recht hilfreich gewesen wäre, ist das auch das falsche Forum ➡ verschoben.



  • Dieser Thread wurde von Moderator/in GPC aus dem Forum Andere GUIs - Qt, GTK+, wxWidgets in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Also ich fange meiner Meinung nach das zyklische Includieren ab in dem ich die Includes in den Headern innerhalb der Direktiven (if !defined und endif) Schreibe.
    Ich hab auch mein Projekt jetzt nochmal durchgeschaut ob ich irgendwo die Child-Header einbinde. Aber diese werden nur einamal in der .cpp Datei includet in der ich von der Klasse Objekte anlegen will und zum einen in der .cpp Datei in der die Methoden der Klasse ausproprogrammiert werden. Oder was verstehst du unter

    ... auch nicht indirekt.

    .
    Ich hab dir den Code jetzt man angehängt. Das die Klassen sind für das Spiel "Schiffe versenken".

    "Parent"
    .cpp

    #include "Schiff.hpp"
    
    Schiff::Schiff(void)
    {
       svg=svg;                  
    }
    
    Schiff::Schiff(GrafikFenster *svg) 
    {
      this->svg=svg;
    }
    
    int Schiff::drehenBug() 
    {
    
    }
    
    int Schiff::setzenBug() 
    {
    
    }
    
    int Schiff::liegtimWasser() 
    {
    
    }
    
    int Schiff::schiessen(unsigned int x, unsigned int y) 
    {
    
    }
    
    int Schiff::positionierenBug() 
    {
    
    }
    

    die Header dazu

    #if !defined(_SCHIFF_H)
    #define _SCHIFF_H
    
    #include "GrafikFenster.hpp"
    #include "GrafikText.hpp"
    //#include "Feld.hpp"    //für Vererbung notwengig
    
    class Feld;
    
    class Schiff //: public Feld   //Vererbung funktioniert nicht!!!!!! :-(
    {
    private:
    	int drehenBug();
    	int setzenBug();
    	int liegtimWasser();
    
    protected:
        GrafikFenster *svg;
    	int laenge;
    	// "zerstoert" wird gesetzt 
    	// wenn Schiff auf 
    	// voller Länge getroffen.
    	int zerstoert;
    	// Legt die X-Koordinate des Bugs des Schiffes fest. 
    	int startX;
    	// Legt die y-Koordinate des Bugs des Schiffes fest. 
    	int startY;
    	// Legt die Richtung von den Startkoordinaten aus fest. nach unten = 1, nach rechts = 2
    	int richtung;
    
    public:
        Schiff(void);
    	Schiff(GrafikFenster *svg);
    	int schiessen(unsigned int x, unsigned int y);
    	// Liefert Ergebnis bei Erfolreichem setzen
    	int positionierenBug();
    	int getroffen();
    
    };
    
    #endif  //_SCHIFF_H
    

    "Child"
    .cpp

    #include "Flugzeugtraeger.hpp"
    
    Flugzeugtraeger::Flugzeugtraeger() 
    {
      laenge = 5;
      richtung = 1; //nach unten - vertikal
    }
    
    void Flugzeugtraeger::starteFlugzeug(int x, int y) 
    {
    
    }
    

    die Header dazu

    #if !defined(_FLUGZEUGTRAEGER_H)
    #define _FLUGZEUGTRAEGER_H
    
    #include "Schiff.hpp"
    #include "Flugzeug.hpp"
    class Schiff;
    
    // 5 Felder
    class Flugzeugtraeger : public Schiff 
    {
    private:
    	int auswahlModus;
    	Flugzeug *sonderwaffe;
    public:
    	Flugzeugtraeger();
    	void starteFlugzeug(int x, int y);
    };
    
    #endif  //_FLUGZEUGTRAEGER_H
    


  • _c0mpiler schrieb:

    Also ich fange meiner Meinung nach das zyklische Includieren ab in dem ich die Includes in den Headern innerhalb der Direktiven (if !defined und endif) Schreibe.

    Wie ich bereits sagte, zyklische Inkludedirektiven "fängst" du damit nicht ab. Du brichst den Kreis auf, das bedeutet aber nicht, dass das grundlegende Problem damit gelöst ist.

    Und warum zeigst du die Dateien für Schiff und Flugzeugtraeger, wenn die nicht funktionierende Vererbungsbeziehung die zwischen Schiff und Feld ist?

    Du musst dafür sorgen, dass "Schiff.hpp" nicht in "Feld.hpp" eingebunden wird.

    Und ganz nebenbei riecht es stark nach einem Designproblem, wenn Schiff von Feld erbt. Ein Schiff "ist" ein Feld? Bist du da sicher?



  • Also die beiden Klassen stimmen schon die ich dir reingestellt habe. Das mit dem Feld und dem Schiff ist ein anderes Thema über das ich mit meinem Prof nochmal reden muss. Ich war auch der Meinung, dass das Feld und das Schiff was anderes ist hab es deshalb auch auskommentiert. Aber ich wollte mich dann nicht mit ihm anlegen.
    Das mit dem zyklischen Includieren hab ich meiner Meinung nach auch nicht ich hab das ganze Projetk nochmal durchgeschaut und find ich nichts zyklisches. Mich würde aber trotzdem interesieren warum das mit den Direktiven nicht funktioniert. Könntest du mir das Erklären?

    MfG



  • _c0mpiler schrieb:

    Also die beiden Klassen stimmen schon die ich dir reingestellt habe.

    Du bekommst also in Flugzeugtraeger.hpp die Fehlermeldung, dass Schiff nicht bekannt ist?

    _c0mpiler schrieb:

    Das mit dem zyklischen Includieren hab ich meiner Meinung nach auch nicht ich hab das ganze Projetk nochmal durchgeschaut und find ich nichts zyklisches.

    Schau bitte mal in "GrafikFenster.hpp" und "GrafikText.hpp" nach. Ich vermute stark, dass in einer dieser Dateien - oder in irgendeiner Datei, die in diesen Dateien per Includedirektive eingebunden wird - wiederum Flugzeugtraeger.hpp eingebunden wird.

    _c0mpiler schrieb:

    Mich würde aber trotzdem interesieren warum das mit den Direktiven nicht funktioniert. Könntest du mir das Erklären?

    Includedirektiven bewirken einfache Textersetzungen. Eine mittels #include eingebundene Datei landet damit vor der Datei, in der die Includedirektive steht. Die Direktiven legen also die Reihenfolge fest.

    Die Include-Guards bewirken, dass dabei keine Datei wiederholt wird, die schon einmal eingebunden wurde.

    Wenn du zyklische Direktiven hast, bedeutet das, dass sich eine Datei (meist über mehrere andere Dateien) selbst einbindet. Du hast also eine Art Schleife in deinen Direktiven.

    Wenn wirklich alle Inkludedirektiven der Schleife notwendig sind, kann dein Programm nicht kompiliert werden, weil mindestens eine Abhängigkeit nicht erfüllt ist.

    Beispiel:
    A.hpp -> #include B.hpp
    B.hpp -> #include C.hpp
    C.hpp -> #include A.hpp

    Wenn jetzt in D.cpp A.hpp eingebunden wird, haben wir diese Reihenfolge:

    C.hpp
    B.hpp
    A.hpp
    D.cpp

    Trotz der Includedirektive in C.hpp ist also der Inhalt von von A.hpp nicht in C.hpp verfügbar.

    Wenn du in D.cpp eine andere Headerdatei einbindest, verschiebt sich das Ganze nur. Aber es bleibt dabei, dass eine Inkludedirektive des Zyklus' nichts bewirkt. Die Include-Guards bewirken nur, dass der Kreis abbricht, aber wo das passiert, und welche Direktive wirkungslos bleibt, hängt vom Inhalt ganz anderer Dateien ab. Es kann natürlich auch sein, dass die Reihenfolge der Header für zwei Übersetzungeinheiten unterschiedlich ist. Und das ist etwas, was man als Ersteller von Headerdateien sicher nicht will.

    Wenn nicht alle Inkludedirektiven notwendig sind, lass einfach die unnötigen weg.


Anmelden zum Antworten