[C++] Vererbte Funktion ruft den Konstruktor der erbenden Klasse auf
-
Guten morgen alle zusammen,
ich bin momentan dran mich etwas mit Programmierung von 2D Spielen zu beschäftigen und versuch seit gestern über eine vererbte Funktion den Konstruktor der erbenden Klasse aufzurufen. Nur weiß ich nicht genau ob ich das richtig gemacht habe , da meine zu vererbende Klasse kein definierten Konstruktor hat, weil er keine Funktion für die Klasse besitzt.
Der Compiler gibt auch ein Fehler aus:
obj\src\main.o:main.cpp:(.text.startup+0x29)||undefined reference to `NEngine::Update()'|
Hier mal der Quelltext:
engine.h :
class NEngine { public: void Update (); protected: void get() { cout << "a" << endl; } /* Einige zu vererbende Funktionen. */ private: /* Einige Variablen. */ bool quit; };
engine.cpp :
int8_t NEngine::Update() { while( !quit) { NEngine(); } }
test.h :
class game : public NEngine { public: game( ); };
test.cpp :
game::game( ) : NEngine() { get(); }
main.cpp :
int main ( int argc, char** argv ) { game *g = new game; g ->Update(); return 0; }
LG
CCodex
-
Sieht so aus, als ob du irgendwo engine.h implementierst, aber nicht engine.cpp. Sieh dir die Fehlermeldung noch einmal genau an.
-
Nö, ich denke das ist nicht der Grund. Deklaration und Definition von NEngine (was soll das "N"-Präfix?) haben unterschiedliche return types: Deklaration ist void, Definition int8_t (ich nehme nicht an, dass int8_t ein typedef auf void ist...). Wenn engine.cpp mitkompiliert wird, solltest du eine entsprechende Fehlermeldung ala "Definition without Declaration" bekommen.
-
arghonaut schrieb:
Nö, ich denke das ist nicht der Grund. [...] Wenn engine.cpp mitkompiliert wird, solltest du eine entsprechende Fehlermeldung ala "Definition without Declaration" bekommen.
Genau das ist ja der Grund für meine Vermutung.
-
@Hacker
Danke die IDE hat die Datei nicht mit implementiert.@arghonaut
Oh habs bei mir ist es anders bei mir ist sind beide void Update.Das "N"-Präfix ist der Anfangsbuchstabe des Names der Engine.
So hab jetzt den Fehler weg bekommen aber die Funktion Update() führt immer noch nicht den Konstruktor von game() aus.
Ist das eigendlich möglich den Konstruktor so aufzurufen ?
-
arghonaut schrieb:
ich nehme nicht an, dass int8_t ein typedef auf void ist...
//stdint.h typedef signed char int8_t;
-
Haha, wo wird eigentlich quit auf false gesetzt?
-
In einer Funktion Init()
Ich hab jetzt nicht alle Funktionen hier geposted da es mir nur um das Aufrufen des Konstruktors geht.
-
CCodex schrieb:
In einer Funktion Init()
Ich hab jetzt nicht alle Funktionen hier geposted da es mir nur um das Aufrufen des Konstruktors geht.
Wär aber gut.
-
Init ist nicht wirklich wichtig ich habs jetzt zum probieren so gemacht :
void NEngine::Update() { quit = false; while( !quit) { Engine(); } return; }
-
Das return ist am Ende unnötig (völlig). Außerdem: Damit die Schleife beendet wird, muss quit true werden.
JAAA'! TAUSEND!
-
Was ist denn jetzt Engine()? Vielleicht postest Du mal ein vollständiges Beispiel, erklärst was Du da machen willst (ich vermute, dass das schon totaler quatsch ist) und erklärst Dein Problem, z.B. die Fehlermeldung.
-
brotbernd schrieb:
ich vermute, dass das schon totaler quatsch ist
Entspann dich.
-
Ist ja nich schlimm wenn ein return da steht
Das quit = true wird durch die Funktion Quit() geändert, aber die funktion brauch ich momentan ja nicht.@brotbernd
Die Fehlermeldung ist schon behoben.Wie ich ja schon geposted hab möchte ich den Konstruktor game() in der vererbten Funktion Update() in der while schleife ausführen.
Mein Problem ist das ich nicht weiß wie ich eine verbindung zu dem Konstruktor game() machen soll über die Klasse NEngine die Funktionen für die Klasse game bereit stellt.
Also besser gesagt ich möchte game() in der Funktion Update() ausführen, aber mein Problem ist das ich nicht weiß wie ich das machen sollte.
-
Jetzt müsstest Du noch erklären was Du Dir von dem Aufruf des Game Konstruktors an dieser Stelle verhoffst?
-
In den Konstruktor game() wird ein Spiel reinprogrammiert.
Über die while schleife ist die Hauptschleife des Spiels.
-
Willst du sowas? :
class NEngine { protected: virtual void do_step() = 0; //Kann man auch in render, ... aufteilen. public: void Update() { while(!quit) do_step(); } }; class Game: public NEngine { protected: void do_step() { get(); } }; int main() { Game g; g.Update(); /* Alternativ (wenn mehrere Game Klassen, die alle von NEngine erben, unterstützt werden sollen */ /* NEngine * e = &g; e->Update(); */ return 0; }
-
Schon mal was von Polymorphie/Vererbung gehört? Sonst ist das vielleicht eine Nummer zu groß für dich; zum return; : Unschönen Code zu programmieren ist eine Straftat, die (manchmal) mit einigen Stunden sinnloser Sucherei und Refactoring bestraft wird ;), also gewöhn dir das besser gleich ab.
-
@TE: Verdammt, natürlich brauchst du Quit()!! quit muss auf true gesetzt werden, sonst eskaliert das zu einer nur durch Gewalt beend-barer Rekursion!
-
Also bei Dir bestehen anscheinend so viele Missverständnisse, dass ich mich schwer tu eine Antwort zu geben. Du solltest Dir dringend nochmal ein Buch vornehmen. In einem Konstruktor implementiert man kein Spiel. Ein Konstruktor wird aufgerufen, wenn eine Instanz einer Klasse erzeugt wird. Man findet dort daher für gewöhnlich Initialisierungsfunktionalität.
Du möchtest jetzt in der Basisklasse Funktionen aufrufen, die in Kindklassen definiert werden. Wen man den Gedanken an das Aufrufen des Konstruktors vergisst ist das auch durchaus ein häufig angewandtes Vorgehen. Häufig wird das als "Template Methode" bezeichnet.class Basis { public: void Update() { while(Condition()) DoUpdate(); } private: virtual void DoUpdate() = 0; }; class Kind { void DoUpdate() { // .... } };
Wenn Du tatsächlich in der while Schleife neue Instanzen von irgendetwas erzeugen willst, dann nennt sich dieser Spezialfall "Factory Method". Die Kindklassen geben dann vor was genau erzeugt wird. Da Konstruktoren in C++ nicht virtuell sein können, wird das über eine separate virtuelle sog. Fabrikmethode gemacht.
class Basis { public: void Update() { while(Condition()) { unique_ptr<Basis> b = Create(); b->DoSomething(); } } private: virtual unique_ptr<Basis> Create() = 0; virtual void DoSomething() = 0; }; class Kind { unique_ptr<Basis> Create() { return unique_ptr<Basis>(new Kind); } };