[nicht mehr aktuell] Variablen für Fremdklasse in Header-Datei
-
Ich habe das Problem, dass ich in einer Klassendefinition innerhalb einer Headerdatei eine Variable definieren will, die ein Objekt aus einer fremden Datei ist.
Folgender Code ist auf das notwendigste reduziert dargestellt:
scene.h
class Scene { //CODE //Panels Panel bg_; //CODE };panel.h
#include "SDL/SDL.h" // domain SDL function #include "SDL/SDL_opengl.h" // OpenGl commands #include "SDL/SDL_image.h" // SDL_image functions #include <iostream> #include <string> class Panel { float xPos_; float yPos_; float width_; float height_; int alpha_; unsigned int texture_; bool draw_; public: Panel(float x,float y,float w, float h); Panel(float x,float y,float w, float h, bool draw); Panel(float x,float y,float w, float h, const std::string &fileName); Panel(float x,float y,float w, float h, const std::string &fileName, bool draw); bool draw(); void setAlpha(int alpha); void setTexture(const std::string &fileName); };Da panel.h erst in der Datei scene.cpp inkludiert wird, ist es klar, dass der Compiler die Klasse in der scene.h noch nicht kennt und folgende Fehlermeldung erscheint:
data/scene.h:20: error: ‘Panel’ does not name a type
Gibt es eine elegante Möglichkeit, das Problem zu umgehen?
Die Variable muss bereits in der Klassendefinition enthalten sein, da Funktionen der Klasse innerhalb einer Schleife abgerufen werden.
-
panel.h einbinden?
-
Schande über mein Haupt...

EDIT
Und wie regle ich das dann mit dem Konstruktor?
Panel::Panel() ist nicht als Konstruktor vorhanden. Oder kann ein zuvor definiertes Objekt so einfach neu definiert werden, wenn ich den Konstruktor Panel::Panel() erstellt habe?
-
Ki schrieb:
Und wie regle ich das dann mit dem Konstruktor?
Panel::Panel() ist nicht als Konstruktor vorhanden.Dann wirst du wohl eine Initiaslisierungliste im Konstruktor von Scene brauchen.
Oder kann ein zuvor definiertes Objekt so einfach neu definiert werden, wenn ich den Konstruktor Panel::Panel() erstellt habe?
Du willst Panel einen Standardkonstruktor hinzufügen? Das ginge zwar technisch gesehen auch, erscheint mir aber wenig sinnvoll. Schließlich hat es ja sicherlich einen Grund, warum Panel derzeit keinen hat.
-
SeppJ schrieb:
Du willst Panel einen Standardkonstruktor hinzufügen? Das ginge zwar technisch gesehen auch, erscheint mir aber wenig sinnvoll. Schließlich hat es ja sicherlich einen Grund, warum Panel derzeit keinen hat.
Damit hast du Recht. Außerdem scheint es so, als müsste ich die Werte dann über Setter nachträglich ändern.
SeppJ schrieb:
Dann wirst du wohl eine Initiaslisierungliste im Konstruktor von Scene brauchen.
Wie stelle ich das an, ohne die Objekte nur für den Konstruktor (sondern für die gesamte Klasse) zu erstellen?
Außerdem würde ich die eigentliche Definition gern innerhalb einer Funktion durchführen:
bool Scene::preScene(SDL_Event event) { if (!texLoaded_) { std::cout << "Load Textures!" << std::endl; Panel bg_(0,0,WINDOW_WIDTH_,WINDOW_HEIGHT_,"data/graphic/prescene/prescene_naudiz.png"); texLoaded_ = true; std::cout << "Textures Loaded!" << std::endl; } //CODE }Die Funktion wird, wie bereits erwähnt, innerhalb eines Loops aufgerufen.
Mit der if-Abfrage will ich wiederum eine einmalige Definition bezwecken.
Neben bool Scene::preScene(SDL_Event event) sollen auch noch andere Funktionen dieser Art innerhalb des Loops aufgerufen werden.
-
Bevor wir hier total aneinander vorbeireden: Dir ist klar, was eine Initialisierungsliste ist, wozu sie gut ist und wie die Syntax ausschaut?
-
Auch nach intensivem Googeln nicht wirklich, daher meine Nachfrage, aber hätte auf etwas in diese Richtung getippt:
Panel::Panel(float x,float y,float w, float h) : [b]xPos_(x), yPos_(y), width_(w), height_(h)[/b] { draw_ = true; texture_ = 0; alpha_ = 255; }
-
Du hast doch ein Problem mit der Scene-Klasse, also mußt du auch in deren Konstruktor eine Initialisierungsliste verwenden.
Wenn du die Werte des Panels erst nach dem Anlegen der Scene erfährst, mußt du die Panel-Klasse so ausbauen, daß du ihre Werte zur Laufzeit ändern kannst, andernfalls setzt du die Parameter im Scene-Konstruktor und nutzt sie anschließend.
-
Man sollte noch anmerken, dass es durchaus möglich ist, während der Initialisierungsliste Klassenmethoden aufzurufen, wenn diese nur Member benutzen, die zu der Zeit schon initialisiert sind. So könntest du eine Methode zum Laden einer Szene benutzen, die dir dann die Werte zum Initialisieren des Panels liefert.
-
CStoll schrieb:
Wenn du die Werte des Panels erst nach dem Anlegen der Scene erfährst, mußt du die Panel-Klasse so ausbauen, daß du ihre Werte zur Laufzeit ändern kannst, andernfalls setzt du die Parameter im Scene-Konstruktor und nutzt sie anschließend.
Heißt im Klartext:
Objekte schon vor dem Loop leer definieren, deklarieren und die Attribute im Loop per Setter verändern?
-
Ki schrieb:
Heißt im Klartext:
Objekte schon vor dem Loop leer definieren, deklarieren und die Attribute im Loop per Setter verändern?Bisher war von einem Loop nie die Rede, es ging nur um den Scene-Konstruktor. Klartext ist also was völlig anderes.
Klartext: Wenn deine Scene-Objekte ein Panel-Objekt als Member haben, wird das Panel-Objekt auf jeden Fall im Konstruktor des Scene-Objektes initialisiert, und zwar vor Betreten des Scene-Konstruktor-Bodys. Das heißt:
Scene::Scene(/* params */) //Hier wird AUF JEDEN FALL der Konstruktor von bg_ aufgerufen { }Das passiert entweder implizit (d.h. der Default-Ctor von Panel wird aufgerufen) oder explizit (per Initialisierungsliste). Da Panel keinen Default-Ctor hat, gehts nur explizit, also so:
Scene::Scene(/* params */) : bg_(someX(), someY(), someW(), someH()) { }Dabei gibts Beschränkungen für das, was du bg_ für die Initialisierung übergeben darfst:
- Die Werte dürfen von den Parametern des Scene-Konstruktors abhängen
- Die Werte dürfen von allen Scene-Membern abhängen, die vor bg_ in der Liste der Klassenmember stehen (weil die vor bg_ initialisiert wurden.
- Die Werte dürfen nicht von Membern abhängen, die weiter unten in der Memberliste stehen.
Für die initialisierung darfst du alle möglichen Funktionen benutzen, sofern die nicht welche von den "späteren" Membern benutzen oder das Scene-Objekt als ganzes.Die Definition der Panel-Klasse, die du gezeigt hast, erlaubt übrigens noch was anderes:
Panel giveMeAPanel(/* params */); Scene::Scene(/* params */) : bg_(giveMeAPanel) //copy-Ctor von Panel aufgerufen { }