Downcast Basisklasse zu abgeleiteter Klasse
-
Hallo,
ich stehe vor einem Problem, wo ein Downcast am sinnvollsten erscheint:
ich habe Clients, die unterschiedliche Spielgegenstände sind, jedoch auch Gemeinsamkeiten aufweisen. Deswegen und weil ich alle Gegenstände über ihre Basisklasse ansteuern will (Polymorphie), habe ich alle Gegenstände von einer Basisklasse vererben lassen:class GameItem; class Weapon: public GameItem {}; class Box: public GameItem {};
Wenn ein Client eine Verbindung mit dem Server herstellt, wird erstmal nur die Basisklasse mit den verfügbaren Infos (IP, Socket, etc.) erstellt, da der Client selber sagen muss, was es für ein Gegenstand ist.
GameItem* newItem = new GameItem(/*...*/);
Basierend auf die Angabe des Typs will ich aus der Basisklasse die entsprechende abgeleitete Klasse machen:
Weapon* weap = dynamic_cast<GameItem*>(newItem);
was wohl nicht geht. Wie kann man das Problem lösen?
Da stellt sich für mich generell die Frage, warum Downcasts nicht erlaubt sind. Durch die Vererbung ist ja sichergestellt, dass jede abgeleitete Klasse dieselben Attribute und Methoden besitzt. Der einzige Haken wäre, dass zusätzliche Attribute der abgel. Klasse nicht initialisiert sind.
-
Die Attribute sind nicht nur nicht initialisiert, sie existieren sogar überhaupt nicht. Du hast schließlich auch keinen Platz dafür besorgt.
Was du da beschreibst hört sich merkwürdig an. Socket in einer Waffe? Wo kommen der Zustand der Waffe her, wenn du ihn nicht irgendwie lieferst?
-
Warum sollte es nicht erlaubt sein?
Allerdings musst du bei dynamic_cast schon den richtigen Typ angeben.
-
[Rewind] schrieb:
was wohl nicht geht. Wie kann man das Problem lösen?
In dem mans richtig macht. dynamic_cast<ZIELTYP>
-
Nein, da habe ich mich vertippt. Ich meinte schon
Weapon* weap = dynamic_cast<Weapon*>(newItem);
Dass es nicht geht, habe ich nicht geschrieben, weil ich einen Fehler beim Kompilieren bekomme, sondern aufgrund vieler Aussagen im Internet, vor allem aus http://www.cplusplus.com/doc/tutorial/typecasting/:
The code above tries to perform two dynamic casts from pointer objects of type Base* (pba and pbb) to a pointer object of type Derived*, but only the first one is successful.
im Abschnitt "dynamic_cast".
-
Mechanics schrieb:
[Rewind] schrieb:
was wohl nicht geht. Wie kann man das Problem lösen?
In dem mans richtig macht. dynamic_cast<ZIELTYP>
Du hast aber schon gesehen, was da mit new erzeugt wird? Und was virtuelles wird auch benötigt.
-
@manni66: nö, hab ich nicht. Da könnte aber immer noch was virtuelles sein, sieht man ja nicht
@[Rewind]: ist doch klar, dass es so nicht geht, wolltest du das tatsächlich so machen?
-
Mechanics schrieb:
wolltest du das tatsächlich so machen?
Ich verstehe nicht warum die rhetorische Frage. Habe ich das Vorhaben und das Problem nicht deutlich genug erklärt?
-
Das hier macht auch keinen Sinn.
[Rewind] schrieb:
GameItem* newItem = new GameItem(/*...*/);
Und für dynamic_cast wird immer min. eine virtuelle Funktion benötigt.
-
[Rewind] schrieb:
Ich verstehe nicht warum die rhetorische Frage. Habe ich das Vorhaben und das Problem nicht deutlich genug erklärt?
Weil du dich auch beim dynamic_cast auch vertippt hast. Also entweder hast du dich hier auch vertippt, oder das was dran steht, macht so offentsichtlich keinen Sinn, dass ich nicht verstehe, wie man die Frage stellen kann.
-
Du kannst mit einem dynamic_cast kein Objekt das du mit new GameItem(...) angelegt hast zu einem Weapon Objekt machen. Damit das funktioniert muss dein Objekt ursprünglich schon mit new Weapon(...) angelegt worden sein. Warum erstellst du das Weapon Objekt nicht einfach zu dem Zeitpunkt wo du jetzt den dynamic_cast hinbauen möchtest?
-
[Rewind] schrieb:
Der einzige Haken wäre, dass zusätzliche Attribute der abgel. Klasse nicht initialisiert sind.
lol
Na wenns weiter nichts ist. Dieses klitzekleine Problem lässt sich ja sicherlich leicht lösen.
-
Ok, ich verstehe, es hat mit dem Speicher zu tun.
sebi707 schrieb:
Warum erstellst du das Weapon Objekt nicht einfach zu dem Zeitpunkt wo du jetzt den dynamic_cast hinbauen möchtest?
Nachdem ich den Post erstellt habe, habe ich das auch überlegt (und umgesetzt). Manchmal muss man das schreiben oder laut sagen, damit man auf die Lösung kommt.
-
[Rewind] schrieb:
Ok, ich verstehe, es hat mit dem Speicher zu tun.
Nein, hat es nicht.
Und nein, du verstehst nicht!
Lies mal nach was RAII ist und überleg dir wozu Konstruktoren gut sind, vielleicht geht dir dann ein Licht auf.