Abstrakte Klasse und Container
-
Hi!
Angenommen ich hab eine Abstrake Klasse Element und zwei davon abgeleitete Klassen Kreis und Kasten
Element definiert getPos(), Kreis getRadius() und Kasten getLength()
Nun hab ich eine ContainerKlasse die Zeiger des Typs Element aufnehmen kann.
Ok, dann füll ich den Container mit ein paar Objekten von Kreis und Kasten...
und nun meine Fragen:
-
Wie kann ich nun feststellen, wenn ich meinen Container durchgehe, ob das Objekt nun von Kreis oder Kasten war?
-
Wie führe ich über den Container eine Methode aus, die nicht in der abstrakten Basisklasse definiert war, sondern erst in der konkreten Klasse? Mit Casten? Also z.b. ((Kreis*)cont[0])->getRadius();
danke schonmal
-
-
Hallo
zum Überprüfen, ob ein Element der Basiklasse einer abgeleiteten Klasse angehört, brauchst du dynamic_cast (oder typeid und cast)
TKreis *Kreis = NULL; TElement *Element = new TKreis(); Kreis = dynamic_cast<TKreis *> (Element); if (Kreis != NULL) { // Kreis benutzen } delete Element;
/Edit : Instanzierung
bis bald
akari
-
danke für die sauschnelle AW
ich bekomm leider mit dem dynamic_cast eine abnormal program termination. Genau in der Zeile, wo er den cast vollziehen sollte
-
Hallo
In Element muß entweder eine gültige Instanz oder NULL sein.
bis bald
akari
-
Hallo,
bevor du dir Gedanken darüber machst, wie du aus dieser Miesere wieder rauskommst würde ich mir erstmal überlegen, warum du dich überhaupt erst reinmanövriert hast.Wenn du eine Liste mit Basisklassenzeigern hast, dann sagst du damit aus, dass der genaue Typ der Objekte für dich nicht relevant ist. Du möchtest also eine Menge von Objekte über ihre Gemeinsamkeiten verwalten.
Wenn du jetzt im nächsten Schritt aufeinmal doch den genauen Typ haben willst, dann stimmt was in deinen Annahmen nicht. Erst wirfst du lustig Typinformationen über Board nur um dann im nächsten Moment volle Typinformation zu fordern. Das ist nicht sinnvoll.Saubere Lösungen:
A) Abstrahiere die durchzuführende Operation und biete diese als (rein) virtuelle Methode in der Basisklasse an.
Wenn A) nicht sinnvoll ist. Behalte die Typinformationen -> ein Container für jeden Typ (statt ein Container für alle Typen).
Den von akari vorgeschlagenen downcast-Hack würde ich wirklich nur im Notfall verwenden.
-
blackwinged schrieb:
ich bekomm leider mit dem dynamic_cast eine abnormal program termination. Genau in der Zeile, wo er den cast vollziehen sollte
Hast du sichergestellt, dass:
A) Deine Basisklasse mindestens eine virtuelle Methode besitzt
Dein Compiler die nötigen RTTI-Informationen generiert (bei einigen Compilern, wie z.B. VC, muss man dies explizit aktivieren).
-
HumeSikkins schrieb:
Hallo,
bevor du dir Gedanken darüber machst, wie du aus dieser Miesere wieder rauskommst würde ich mir erstmal überlegen, warum du dich überhaupt erst reinmanövriert hast.Wenn du eine Liste mit Basisklassenzeigern hast, dann sagst du damit aus, dass der genaue Typ der Objekte für dich nicht relevant ist. Du möchtest also eine Menge von Objekte über ihre Gemeinsamkeiten verwalten.
Wenn du jetzt im nächsten Schritt aufeinmal doch den genauen Typ haben willst, dann stimmt was in deinen Annahmen nicht. Erst wirfst du lustig Typinformationen über Board nur um dann im nächsten Moment volle Typinformation zu fordern. Das ist nicht sinnvoll.Saubere Lösungen:
A) Abstrahiere die durchzuführende Operation und biete diese als (rein) virtuelle Methode in der Basisklasse an.
Wenn A) nicht sinnvoll ist. Behalte die Typinformationen -> ein Container für jeden Typ (statt ein Container für alle Typen).
Den von akari vorgeschlagenen downcast-Hack würde ich wirklich nur im Notfall verwenden.
Hi!
Da hst du auf jeden Fall recht. Nur weiß ich nicht so recht, wie das modellieren soll.
Hintergrund: Ess soll einen Container geben, der Objekte zwei verschiedener Klassen beinhaltet. Beide Klassen haben die Methode getData() - die eine gibt aber ein ByteArray zurück, die andere eine Struktur.
-
Was willst du denn mit deinem Kreis und Kästchen machen? Transformationen, kannst du ja per rein virtuelle Funktion implementiren. Wenn du sowohl ein Kreis als auch ein Kästchen an eine Funktion übergeben willst die ein Polygon als Parameter nimmt, dann ist operator T wahrscheinlich was du suchst.
Wenn du den Radius eines Kreises herausfinden willst, dann musst du erst einmal wissen, ob es sich um einen Kreis handelt. Als entweder musst du das testen (dynamic_cast/typeid) oder nie vergessen (2 verschiedene Container für Kreise und Kästchen).
Beide Vorgehensweisen haben ihre Vorteile und Nachteile. 2 verschiedene Container sind schneller allerdings musst du einen neuen hinzufügen wenn du wenn du eine neue Figur hinzufügst. Dies bedeutet Änderungen an deinem Code un daher eine Fehlerquelle. Bei der dynamic_cast/typeid Methode wirst du eingentlich nur Code hinzufügen müssen der direkt mit der Figur zu tun hat.
-
blackwinged schrieb:
Hintergrund: Ess soll einen Container geben, der Objekte zwei verschiedener Klassen beinhaltet. Beide Klassen haben die Methode getData() - die eine gibt aber ein ByteArray zurück, die andere eine Struktur.
Genau das ist dein Problem. Du musst die Klassen umbauen, oder wrappen oder sonstwas machen, dass getData() den selben typen returned. denn sonst heisst die funktion zwar gleich, aber die signatur ist anders. und das heisst: die beiden funktionen sind unterschiedlich.
und das passt nicht
-
HumeSikkins schrieb:
Saubere Lösungen:
A) Abstrahiere die durchzuführende Operation und biete diese als (rein) virtuelle Methode in der Basisklasse an.
Wenn A) nicht sinnvoll ist. Behalte die Typinformationen -> ein Container für jeden Typ (statt ein Container für alle Typen).
C) Visitor
-
ssm schrieb:
HumeSikkins schrieb:
Saubere Lösungen:
A) Abstrahiere die durchzuführende Operation und biete diese als (rein) virtuelle Methode in der Basisklasse an.
Wenn A) nicht sinnvoll ist. Behalte die Typinformationen -> ein Container für jeden Typ (statt ein Container für alle Typen).
C) Visitor
OK. Würde ich allerdings nicht vorschlagen ohne die Situation genauer zu kennen. Visitor ist in Sachen Nachteilen ein sehr kostspieliges DP, dass auf jeden Fall zu starken Abhängigkeiten führt (und in der azyklischen Variante zu vielen Klassen).
Bevor ich dieses DP vorschlage muss ich zumindest die Stabilität der zu besuchenden Hierarchie kennen und eine Ahnung davon haben, wie wahrscheinlich es ist, dass neue Operationen hinzugefügt werden sollen.
-
HumeSikkins schrieb:
Bevor ich dieses DP vorschlage muss ich zumindest die Stabilität der zu besuchenden Hierarchie kennen und eine Ahnung davon haben, wie wahrscheinlich es ist, dass neue Operationen hinzugefügt werden sollen.
das ist alles richtig, leider kann ich selber noch nicht auf Deutsch so gut erklähren