Pointer auf abstrakte KLassen
-
Hi Forum,
ich versuche gerade ein Design(Strategy)Patternzu implementiern. was unegfähr wie folgt aussiehtclass AbstractStrategy { public: virtual void test() = 0; };class Strategy1 : public AbstractStrategy { public: virtual void test(){ cout << "Strat1\n"} Strategy1(); };class Strategy2 : public AbstractStrategy { public: virtual void test(){ cout << "Strat2\n"} };Sieht die Main wie folgt aus funktioniert auch alles wunderbar
int main() { Strategy1 s1(); Strategy2 s2(); AbstractStrategy * pToStrat = &s1; pToStrat->test(); pToStrat = &s2; pToStrat->test(); }Sooo nun kommt Code der nicht funktioniert
//Global AbstractStrategy * pToStrat; void initStrat() { AbstractStrategy * pToStrat = new Strategy1(); } int main() { initStrat(); pToStrat->test(); }Ich denke mal der Code funktioniert nicht, weil in der Funktion initStrat der Pointer auf ein Objekt verwiesen wird, das aber nur innerhalb vin initStrat() existiert.
Meine Frage ist also, wie kann ich es schaffen, dass mein Pointer hinterher auf ein "ordentliches" Objekt zeigt, welches ich in einer anderen Funktion/Methode erstellt habe ?
Ich danke schonmal in vorausChris
-
TrixTrax schrieb:
...
Sieht die Main wie folgt aus funktioniert auch alles wunderbarint main() { Strategy1 s1(); Strategy2 s2(); ...Glaube ich nicht.
Es hilft nichts, wenn Du 2 Funktionen definierst, die keinen Parameter haben und ein Strategy1-(bzw.2)-Objekt zurückgeben. Das wird Dir auch Dein Compiler ankreiden ....

und gleich die 2 Standardhinweise:
1.) Nimm doch bitte die cpp-Tags ...
2.) "funktioniert nicht" ist keine Fehlerbeschreibung.Gruß,
Simon2.
-
TrixTrax schrieb:
Sooo nun kommt Code der nicht funktioniert
...
Ich denke mal der Code funktioniert nicht, weil in der Funktion initStrat der Pointer auf ein Objekt verwiesen wird, das aber nur innerhalb vin initStrat() existiert.Ganz davon abgesehen, das man globale Variablen möglichst meiden sollte... (Und du auch das Objekt am Schluss wieder löschen solltest).
Du deklarierst hier zwei verschiedene Variablen, die nichts miteinander zu tun haben:
//Global AbstractStrategy * pToStrat; // Globale Variable void initStrat() { // Lokale Variable: AbstractStrategy * pToStrat = new Strategy1(); }Wenn du die Globale setzen willst:
//Global AbstractStrategy * pToStrat; void initStrat() { pToStrat = new Strategy1(); }cu André
-
Oder gleich:
AbstractStrategy* initStrat() { static AbstractStrategy * pToStrat = new Strategy1(); return pToStrat }Inkl. aller Probleme von "Singletons und Singletonartigen"...
Gruß,
Simon2.
-
Simon2 schrieb:
Inkl. aller Probleme von "Singletons und Singletonartigen"...
Und mit dynamischer Speicherverwaltung. Gerade im Zusammenhang mit
staticist die Frage sehr heikel, wer den Speicher freigibt. Also wenns geht auf dem Stack (bzw. statischem Speicherbereich beistatic) arbeiten, RAII nutzen, oder wenigstens manuell freigeben.
-
Erstmal danke für die Antworten

Ja das Programm sieht nicht 100%tig so aus, ich dachte nur so wäre mein Problem einfacher zu verstehen.
Und bei dieser Abstraktion habe ich selber einen Fehler reingebaut, bezüglich global bzw. lokal. Bevor mir noch mehr Fehler unterlaufen. Hier vielleicht Auszüge aus dem original Code.So also einmal das "Interface"
#ifndef _ABSTRACTCOLLITIONDETECTION_H #define _ABSTRACTCOLLITIONDETECTION_H #include <GL/glut.h> class AbstractCollisionReactor { public: virtual void react(GLfloat **array, void* comp) = 0; }; #endif /* _ABSTRACTCOLLITIONDETECTION_H */Diese Abstrakte Klasse/Interface wird von einer weiteren Klasse verwendet
class Component { protected: AbstractCollisionReactor * collisionReactor; MyVertex center; . . . public: Component(GLint type, GLint numberOfVertics, GLint typeOfReactor) { . . . switch(typeOfReactor) { case 0: collisionReactor = new WallCollisionReactor(); //Testen des Patterns. Funktioniert collisionReactor->react(NULL, NULL); break; case 1: collisionReactor = new EnemyCollisionReactor(); //Testen des Patterns. Funktioniert collisionReactor->react(NULL, NULL); break; } } void react(GLfloat** array, Component *comp) { collisionReactor->react(array, comp); } };So im switch case "teste" ich ja das mit den Stratgey. Und das funktioniert auch einwandfrei, es erscheint meine eigene Fehlermeldung, dass die Parameter null sind und als Zusatz lasse ich mir ausgeben welches Pattern gerade verwendet wird (also einfaches cout in den konkreten Klassen).
Sooo und zum Thema es funktioniert nicht ist keine Beschreibung:
Komme ich nun bei der Collision Detection zur Stelle
for (int counter = 0; counter < numberOfComponents; counter++) { if(doCollide(arrayOfComponents[counter], gamer) { cout << "Aua\n" ; arrayOfComponents[counter].react(informationArray, gamer); cout << "Du hast mich getroffen\n" ; } }Erscheint noch auf meiner Console:
Aua
SegmentationFaultIch habe auch einfach mal nur couts verwendet in den Methoden react() von Wall- bzw EnemyCollisionReactor, um auszuschließen, dass ich nicht so einen Fehler verursache. Das Ergebnis bleibt das gleiche. Auch mit dem Debugger komme ich nur bis collisionReactor->react(array, comp); Innerhalb der Methode react() der Component Klasse.
Erstmal Entschuldigung, dass ich nicht sofort mit dem richtigen Code rausgerückt habe.
MfG Chris
-
Und "arrayOfComponents[counter]" ist zum Zeitpunkt des react-Aufrufs noch i.O.?
Denn wenn der react-Aufruf zum segfault führt, egal was du da drinnen machst, deutet das eigentlich darauf hin...
Ist arrayOfConmponents ein ARRAY oder eine std::list, bzw. std::vector?
Falls ein Array, wäre es angebracht, mal ne liste zu verwenden, und vor dem Zugriff auf das [conter]'te Objekt zu prüfen ob du nicht schon outOfRange bist.
-
Ist Dein Destruktor
virtual?