Fehlender Typbezeichner



  • Hallo Leute !

    Ich habe folgendes Problem:

    Ich habe 2 Klassen:
    -ZustandsManager
    -Intro

    Die ZustandsManager Klasse wird in der main.cpp inkludiert.
    Die Intro Klasse wird in der ZustandsManager Klasse inkludiert

    Die Klasse ZustandsManager erzeugt eine neue Intro Klasse und soll ihr einen Pointer auf sich selber übergeben:

    Zustaende.push_back(new Intro("Intro",this));
    

    Nun das Problem:
    Ich möchte in der Intro Klasse den Pointer zu der ZustandsManager Klasse als Member speichern.

    Normal würde das ja so aussehen:

    ZustandsManager * pointer;
    

    Doch komischerweiße meckert mein Compiler nun rum und meint er kennt ZustandsManager in der Klasse Intro nicht, dabei wird Intro ja erst nach ZustandsManager inkludiert.

    Wie kann ich dieses Problem beheben?

    Code:

    main.cpp

    #include <iostream>
    #include <SFML/System.hpp>
    #include <SFML/Audio.hpp>
    #include <SFML/Window.hpp>
    #include <SFML/Graphics.hpp>
    #include <Blackanges/Input.h>
    #include <time.h>
    
    #include "ZustandsManager.h"
    
    int main()
    {
        sf::VideoMode VMode(sf::VideoMode::getDesktopMode());
        sf::RenderWindow window(VMode, "4 Gewinnt",sf::Style::Fullscreen);
    
    	window.setVerticalSyncEnabled(true);
    
    	//sf::Font font;
    	//font.loadFromFile("arial.ttf");
    
    	ZustandsManager derZustandsManager;
    
    	srand (time(NULL));
    
        while (window.isOpen())
        {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
    
                    window.close();
            }
    
    		window.clear();
    
    		derZustandsManager.bearbeite();
    		derZustandsManager.zeichne(window);
    
            window.display();
        }
    
        return 0;
    }
    

    Zustandsmanager.h

    #pragma once
    
    #include "Zustand.h"
    #include "Intro.h"
    #include "Menue.h"
    #include "Optionen.h"
    #include "Spiel.h"
    #include "Pause.h"
    #include "Ende.h"
    
    class ZustandsManager{
    
    private:
    	//Container beinhalted die Zustände
    	std::vector <Zustand*> Zustaende;
    
    public:
    
    	enum ZustaendeNamen{
    		Zustand_Intro,
    		Zustand_Menue,
    		Zustand_Optionen,
    		Zustand_Spiel,
    		Zustand_Pause,
    		Zustand_Ende
    	};
    
    	//Konstruktor
    	ZustandsManager(){
    
    		Zustaende.push_back(new Intro("Intro",this));
    
    	}
    
    	//Destruktor leert den Zustands-Container -> kein Speicherleck
    	~ZustandsManager(){
    		Zustaende.clear();
    	}
    
    	//Bearbeitet alle Zustände
    	void bearbeite(){
    		for(int i=0;Zustaende.begin()+i<Zustaende.end();i++){
    			Zustaende[i]->bearbeite();
    		}
    	}
    
    	//Zeichnet alle Zustände
    	 void zeichne(sf::RenderTarget& target) const{
    		for(int i=0;Zustaende.begin()+i<Zustaende.end();i++){
    			Zustaende[i]->zeichne(target);
    		}
    	}
    
    	void neuerZustand(ZustaendeNamen id){
    		switch(id){
    
    //		case 0:{Zustaende.push_back(new Menue("Menue");break;}
    		case 1:{break;}
    		}
    
    	}
    
    };
    

    Intro.h

    #pragma once
    
    class Intro : public Zustand{
    
    private:
    
    	sf::String  s_Name;
    	bool fertig;
    	bool geladen;
    
    	sf::Sprite Logo;
    	sf::Texture t_Logo;
    
    	ZustandsManager * zm_pointer;
    
    	void eingabe(){
    
    		if(Keyboard.pressed(sf::Keyboard::B))fertig=true;
    
    	}
    
    public:
    
    	//Konstruktor
    	Intro(const sf::String name,ZustandsManager * pointer) : s_Name  (name), fertig (false) 
    	{
    		t_Logo.loadFromFile("Bilder/Logo.png");
    		Logo.setTexture(t_Logo);
    	//	zm_pointer=pointer;
    
    	}
    
    	//Zeichnet die Klasse
    	void zeichne(sf::RenderTarget& target) const{	
    
    		target.draw(Logo);
    
    	}
    
    	//Bearbeitet die Klasse
    	void bearbeite(){
    
    		eingabe();
    
    		if(fertig){
    		//	zm_pointer->neuerZustand(zm_pointer->Zustand_Menue);			
    		}
    		fertig=false;
    
    	}
    
    	//Gibt den Namen des Zustandes aus
    	sf::String gebeName() {
    		return  s_Name;
    	}
    
    };
    

    MfG
    Er4zoX



  • er4zox schrieb:

    Doch komischerweiße meckert mein Compiler nun rum und meint er kennt ZustandsManager in der Klasse Intro nicht, dabei wird Intro ja erst nach ZustandsManager inkludiert.

    Wieso komischerweise? Du hast ZustandsManager nicht inkludiert und deswegen kennt er ihn nicht. Ich würde das logisch statt komisch nennen.

    Allgemein: Wenn sich 2 Klassen kennen müssen ist irgendwas im Design kaputt. Überdenke nochmal, ob das wirklich nötig ist.

    Wenn du es für nötig erklärst sieh dir forward declarations an, also sowas wie class ZustandsManager;. Das reicht um einen Zeiger zu deklarieren.



  • Hm ok danke schonmal, ich wollte halt dass die Intro Klasse dem ZustandsManager einen Befehl schickt, sobald das Intro fertig ist. Dazu müssen sich ja beide Klassen kennen.

    Gibt es da eventuell einen anderen Lösungsansatz außer dass der ZustandsManager das Intro nach jedem durchgang abfragt ob es fertig ist?



  • Jau, gibt´s. Nennt sich Observer Pattern.



  • Dein Destruktor ~ZustandsManager() löscht nur Elemente im Vektor Zustaende. Er gibt _nicht_ den Speicher wieder frei, der mit den einzelnen Zeigern verknüpft ist. Du musst delete auf jedem Zeiger aufrufen.
    Evtl. kannst Du auch einen unique_ptr nehmen, oder sonstwie umdesignen, dass Du keinen D'tor brauchst.


Anmelden zum Antworten