Klasse hat ein Objekt einer anderen Klasse -> Fehlermeldung?



  • Hallo Community,
    ich habe mich seit heute an ein SFML 2D RPG gesetzt. Da hab ich eine Game Klasse und eine Player Klasse. Die Game Klasse enthält ein Objekt der Player Klasse. Ausgegeben wird mir aber ein Fehler -> "p" unbekannter Überschreibungsspezifizierer und unbekannter Typspezifizierer in der Datei Game.h.

    // Player.h
    #pragma once
    #include "Game.h"
    class Player
    {
        friend class Game;
    
    protected:
        /* Alle möglichen Werte für Player */
    
    };
    
    // Game.h
    #pragma once
    #include "Player.h"
    class Game
    {
    public:
        /* Konstruktor, Destruktor und andere Funktionen */
    private:
        /* Ein paar Werte die unwichtig sind */
        Player p;
    };
    

    Ich weiß nicht wie ich den Fehler beheben soll. Danke schon mal für die Hilfe :).



  • Wenn jemand Player.h inkludiert, dann kommt da gleich mal die Zeile

    #include "Game.h"

    Also wird an der Stelle jetzt der Inhalt von Game.h reinkopiert.
    Das

    #include "Player.h"

    in Game.h wird aber ignoriert, da Player.h ja schon inkludiert wurde und ein

    #pragma once

    enthält.
    Danach folgt dann die Definition der Klasse Game , welche eine Instanz von Player enthält. Noch bevor Player deklariert/definiert wird.

    Daher der Fehler.

    Lösung: Entferne das #include "Game.h" aus Player.h .



  • 💡 💡 💡
    👍 Perfekt danke. Funktioniert! 😃



  • Da stellt sich mir noch eine Frage:
    Woher weiß die Klasse Player dann was Game überhaupt ist wenn die Datei Game.h nicht inkludiert wird?
    Ist bei "friend class Game" deswegen das class da?
    Wirkt das dann so ähnlich wie ein Prototyp oder wie ist das? 😕



  • Ist bei "friend class Game" deswegen das class da?

    Genau.

    Mit dem class in diesem Konstrukt teilst du mit: das was da "befreundet" wird ist eine Klasse. Die Zeile dient dann gleichzeitig als sog. "forward declaration" der Klasse Game .

    So eine "forward declaration" kann man natürlich auch ohne friend machen, in dem Fall würde man (dann allerdings ausserhalb der Klasse Player) einfach class Game; schreiben.
    In dem Fall könnte man das class in friend class Game; dann weglassen. Würde dann so aussehen

    // Player.h
    #pragma once
    
    class Game;       // Forward declaration of Game
    
    class Player
    {
        friend Game;  // Refers to the class Game that we forward-declared above
    
    // ... 
    };
    

    Praktisch ist das z.B. wenn man irgendwo z.B. einen Zeiger auf Game als Parameter übergeben möchte. Dann ist eine "forward declaration" ausreichend, und man muss nicht die ganze Definition der Klasse Game per #include reinholen.

    // Foo.h
    #pragma once
    
    class Game;       // Forward declaration of Game
    
    class Foo
    {
    public:
        void SomeMemberFunction(Game* game); // OK, because of the forward declaration above we know that Game is a class,
                                             // which is all we need to know at this point.
    // ... 
    };
    

    multipilz5 schrieb:

    Wirkt das dann so ähnlich wie ein Prototyp oder wie ist das? 😕

    Ganz genau so.
    Im Falle von Klassen kenne ich nur den Ausdruck "forward declaration".
    Bei Funktionen wird oft der Begriff "Prototyp" verwendet. Gemeint ist damit einfach nur die "forward declaration" einer Funktion.


Log in to reply