Dynamic und Static Cast? oder einfach nur ein normales Cast?
-
Shade Of Mine schrieb:
Ob es eine liste, ein baum, ein dreieck oder ein bunter Hund ist, ist egal.
oder ein bleicher hund?
wie auch immer, manchmal ist das ganz und gar nicht egal!Shade Of Mine schrieb:
Worum es geht ist: ich schmeisse die Typinformation zum Fenster hinaus und nachher spring ich dann selber aus dem Fenster um sie wieder einzusammeln.
Da sollte sich sofort die frage stellen: warum wegschmeissen wenn ich dann den Müll druchsuchen muss um es wieder zu finden? Warum nicht einfach nicht wegschmeissen, dann spar ich mir den müll anzufassen.der vergleich hinkt. wenn es so wäre, dann würde es kein 'dynamic_cast' geben.
-
pale dog schrieb:
Shade Of Mine schrieb:
Worum es geht ist: ich schmeisse die Typinformation zum Fenster hinaus und nachher spring ich dann selber aus dem Fenster um sie wieder einzusammeln.
Da sollte sich sofort die frage stellen: warum wegschmeissen wenn ich dann den Müll druchsuchen muss um es wieder zu finden? Warum nicht einfach nicht wegschmeissen, dann spar ich mir den müll anzufassen.der vergleich hinkt. wenn es so wäre, dann würde es kein 'dynamic_cast' geben.
Ich weiß, wenn es nach dir ginge, könnte man C++ komplett abschaffen.
Und der Punkt ist auch nicht, daß man dynamic_cast komplett weglassen sollte. Aber bevor man es anfasst, sollte man sich sehr genau überlegen, ob es denn wirklich notwendig ist (und in mindestens 99% der Fälle ist es tatsächlich günstiger, die notwendigen Typ-Informationen von vornherein bei der Hand zu haben, anstatt sie mühsam rekonstuieren zu müssen).
-
Konrad Rudolph schrieb:
[...]
Angenommen, wir wollen nun alle Buttons auf dieser Form durchlaufen und sie anklicken. Der beste Weg dafür ist folgendes:for (Iterator<Control> c = form->controls.begin(); c != form->controls.end(); ++c) { Button* b = dynamic_cast<Button*>(c); if (b) b->perform_click(); }
Alles andere (z.B. einen Extra-Container für Buttons zu verwalten) verursacht ein enormes Zusatz-Overhead und ist selten praktisch.
Ob das der Beste Weg ist, sei mal dahin gestellt. Es ist zumindest ein gangbarer Weg.
Der Code hat mich direkt an eine andere Situation erinnert, wo ein dynamic_cast sinnvoll ist: das azyklische-Visitor-Pattern benötigt in seiner Implementation ebenfalls einen dynamic_cast, hilft gleichzeitig aber dabei dynamic_casts zu reduzieren
-
wieso mühsam? ist der cast-befehl so aufwendig?
ich dachte wenn ich in meine std::list<A*> B und C speichere, werden ja die typinfos sicher durch polymorhie mitgespeichert.... und könne so einfach gecastet werden..
-
HumeSikkins schrieb:
for (Iterator<Control> c = form->controls.begin(); c != form->controls.end(); ++c) { Button* b = dynamic_cast<Button*>(c); if (b) b->perform_click(); }
Ob das der Beste Weg ist, sei mal dahin gestellt.
Jetzt hast Du mich neugierig gemacht. Was wäre denn eine bessere Alternative?
-
CStoll schrieb:
pale dog schrieb:
Shade Of Mine schrieb:
Worum es geht ist: ich schmeisse die Typinformation zum Fenster hinaus und nachher spring ich dann selber aus dem Fenster um sie wieder einzusammeln.
Da sollte sich sofort die frage stellen: warum wegschmeissen wenn ich dann den Müll druchsuchen muss um es wieder zu finden? Warum nicht einfach nicht wegschmeissen, dann spar ich mir den müll anzufassen.der vergleich hinkt. wenn es so wäre, dann würde es kein 'dynamic_cast' geben.
Ich weiß, wenn es nach dir ginge, könnte man C++ komplett abschaffen.
ach nöööö... dann wär's aber ganz schön langweilig hier.
-
Nicht mühsam für dich, aber mühsam hinter den Kulissen.
Beantworte doch mal die Frage: Wenn B und C so verschieden sind, daß du sie nicht über ein gemeinsames Interface ansprechen kannst - warum machst du dir dann überhaupt die ühe, sie in einer gemeinsamen list<> unterzubringen? Entweder die Klassen sind ähnlich aufgebaut, dann nimmt man den A-Zeiger und ruft dessen (virtuelle) Methoden auf - oder sie haben nichts gemeinsam, dann verwaltet man sie auch unabhängig voneinander.
-
BorisDieKlinge schrieb:
wieso mühsam? ist der cast-befehl so aufwendig?
Ja, dynamic_cast ist aufwendig. Man braucht ab und an dynamic_cast, aber man sollte es vermeiden wenn möglich (Und erst recht sollte man zweimal überlegen es beim Interieren über eine große Liste einzusetzen).
BorisDieKlinge schrieb:
ich dachte wenn ich in meine std::list<A*> B und C speichere, werden ja die typinfos sicher durch polymorhie mitgespeichert.... und könne so einfach gecastet werden..
Leider ist das nicht ganz so einfach. Denn A ist die Basisklasse. B und C wissen natürlich das sie auch ein A sind, aber umgekehrt ist der weg nicht ganz so leicht.
cu André
-
Hallo
@ Boris :
Richtig das geht schon. dynamic_cast ist deshalb verpönt weil es eben zur Laufzeit eine Bedingung auswerten muß. Je nach Implementation der RTTI ist das in mehr oder weniger zusätzlichen Taktschritten erledigt, die nicht gebräucht würden wenn der Basistyp ausreicht. Wenn du kein dynamic_cast oder typeid in deinem Programm verwendest kannst du dem Compiler das RTTI sogar ganz ausstellen.bis bald
akari
-
pale dog schrieb:
wie auch immer, manchmal ist das ganz und gar nicht egal!
langsam nervst du.
welche datenstruktur man verwendet um das zu machen ist sowas von irrelevant für das thema.Shade Of Mine schrieb:
Worum es geht ist: ich schmeisse die Typinformation zum Fenster hinaus und nachher spring ich dann selber aus dem Fenster um sie wieder einzusammeln.
Da sollte sich sofort die frage stellen: warum wegschmeissen wenn ich dann den Müll druchsuchen muss um es wieder zu finden? Warum nicht einfach nicht wegschmeissen, dann spar ich mir den müll anzufassen.der vergleich hinkt. wenn es so wäre, dann würde es kein 'dynamic_cast' geben.
und genau das meine ich: du verstehst es nicht und willst es scheinbar nicht verstehen.
ich habe lang und breit geschrieben warum man in 99% der fälle keinen dynamic_cast braucht - ich war noch nie in der situation einen dynamic_cast zu brauchen. und da ich denke ich nun schon ein wenig code geschrieben habe und so ziemliche jede person die ich schätze ähnliche erfahrungen gemacht hat, ist es durchaus zulässig zu sagen dass dynamic_cast in 99% der fälle unnötig ist.
ich habe aber ebenfalls gesagt, dass ausnahmen die regel bestätigen.
nur weil man etwas nicht dauernd verwendet ist es nicht komplett unnütz. zum beispiel verwende ich feuerlöscher selten. um genau zu sein habe ich noch nie einen verwendet. aber ich würde deshalb nicht so weit gehen sie abzuschaffen.
denk darüber mal nach.
-
Shade Of Mine schrieb:
pale dog schrieb:
wie auch immer, manchmal ist das ganz und gar nicht egal!
welche datenstruktur man verwendet um das zu machen ist sowas von irrelevant für das thema.
wieso glaubst du das?
man kann doch sowas z.b. machen, um die vorteile eine bestimmten datenstruktur zu nutzen (siehe auch Konrad Rudolphs beispiel mit dem controls-container).
es geht ja nicht darum, alle objekte auf einen ungeordneten haufen zu werfen, wie du es so schön beschrieben hast...
-
pale dog schrieb:
Shade Of Mine schrieb:
pale dog schrieb:
wie auch immer, manchmal ist das ganz und gar nicht egal!
welche datenstruktur man verwendet um das zu machen ist sowas von irrelevant für das thema.
wieso glaubst du das?
man kann doch sowas z.b. machen, um die vorteile eine bestimmten datenstruktur zu nutzen (siehe auch Konrad Rudolphs beispiel mit dem controls-container).
Ja, sicher - in der Praxis spielen die Feinheiten einer gegebenen Datenstruktur womöglich eine Rolle, aber um diese Datenstrukturen geht es hier nicht. Hier geht es darum, daß sich jemand nicht die Mühe gemacht hat, ein vernünftiges Design zu entwerfen, und dieses Manko nun versucht, mit einigen Casts auszubügeln (und dafür spielt es dann keine Rolle, ob die Objekte in einer Liste, einem Binärbaum oder in einem Hundehaufen untergebracht sind).
PS: Und wenn du hier nichts produktives beitragen kannst, solltest du dich lieber in deinen Sandkasten zurückziehen. (Sorry, das mußte jetzt raus)
-
CStoll schrieb:
PS: Und wenn du hier nichts produktives beitragen kannst, solltest du dich lieber in deinen Sandkasten zurückziehen. (Sorry, das mußte jetzt raus)
ok, tut mir leid. ich lasse euch jetzt in diesem thread in ruhe.
(du kannst ja meine postings hier löschen, wenn sie dich stören).
-
pale dog schrieb:
CStoll schrieb:
PS: Und wenn du hier nichts produktives beitragen kannst, solltest du dich lieber in deinen Sandkasten zurückziehen. (Sorry, das mußte jetzt raus)
ok, tut mir leid. ich lasse euch jetzt in diesem thread in ruhe.
Ich schlage vor, du gehst noch einen Schritt weiter und lässt uns in diesem Board in Ruhe.
-
CStoll schrieb:
pale dog schrieb:
CStoll schrieb:
PS: Und wenn du hier nichts produktives beitragen kannst, solltest du dich lieber in deinen Sandkasten zurückziehen. (Sorry, das mußte jetzt raus)
ok, tut mir leid. ich lasse euch jetzt in diesem thread in ruhe.
Ich schlage vor, du gehst noch einen Schritt weiter und lässt uns in diesem Board in Ruhe.
das ganze board? einschliesslich aller unterforen?
-
pale dog schrieb:
das ganze board? einschliesslich aller unterforen?
Eigentlich meinte ich nur das C++ Board, aber wenn du komplett verschwinden willst, ist mir das noch lieber
-
CStoll schrieb:
aber wenn du komplett verschwinden willst, ist mir das noch lieber
na gut, dann werde ich mich hiermit offiziell verabschieden.
man soll zwar aufhören, wenn's am schönsten ist, aber egal.
an alle: viel spass noch, war lustig hier und ich habe viel gelernt von euch
-
@CSToll u. Pale dog: Nur wegen meinem lächerlichen Thread, müsst ihr euch nich bekriegen.. hier muss auch keiner gehen ... was ist denn bei euch los...
-
@Boris: Nur um dich zu beruhigen - es geht nicht um diesen Thread. Die "Feindschaft" zwischen pale dog (alias vista/net/net/...) und mir besteht schon eine Weile und kocht wohl bei jeder Gelegenheit wieder neu auf.
-
Noch mal zum Thema zurück zu kommen:
ich habe eine CAllocation klases, welche Knoten als CAllocNode Klasse in einer Baumstruktur verwaltet. Durch diverse funktionen bspw.
CAllocNode* add(CAllocNode *pNode
);
so nun hab ich diverse klassen, ich nenn sie mal A,B,C welceh von CAllocNode abgeleitet sind.
A,B,C enthalten spezifische methodne und parameter, wobei CAllocNode nur die verwaltung methoden add, delete, instert etc. enthält.
später kann ich dann quasie die A,B,C objekt als knoten in der Baumstrutkur verwalten
A->add(new A(...));
Problem ist nun, das add nicht ein A pointer sonder der CAllocNode Pointer zurückliefert (siehe oben Mehtodenrumpf), deswegen muss ich dies mit static_cast machen:
A *p= static_cast<A*> (A->add(new A(..)));
verstanden?