Unterschiede im Casting
-
Hi,
ich habe bisher nicht ganz verstanden wann ich normal casten kann und wann ich static & dynamic casts brauche?
MyClass *m_pMyClass = (MyClass*)m_pMyClassB; m_pMyClass = static_cast<MyClass*>m_pMyClassB; m_pMyClass = dynamic_cast<MyClass*>m_pMyClassB;Hängt das irgendwie von der Implementierung von MyClassB ab oder wann brauche ich die anderen?
danke
-
Es geht fast alles mit der Variante (MyClass*), bis auf einige Fälle des dynamic_cast. Trotzdem sollte man den ()-Cast in C++ nicht benutzen. Er kann eben zu viel. Die C++-Casts können jeder für sich etwas weniger, dadurch castet man nicht aus versehen zu viel weg.
static_cast für einfache Typkonvertierungen verwandter Typen. static_cast kann zum Beispiel kein const wegcasten. Daher kann es Dir nicht passieren, daß Du damit irrtümlich außer der beabsichtigten Typumwandlung aus Versehen gleich noch ein const mit beseitigst.
const_cast kann nur eine Sache: consts wegmachen.
reinterpret_cast ist der Vorschlaghammer unter den C++-Casts. Nötig für so brachiale Methoden wie mach aus dem int nen Pointer.
dynamic_cast benutzt Typinformationen eines Objektes zum sicheren downcast.
-
Vielen Dank!
Also ist dynamic_cast am sichersten - ist es auch am schnellsten oder wäre das static_cast? Sollte man denn wenn möglich (solange es funtioniert) dynamic_cast verwenden? Welche Typinformationen benutzt es denn zum casten?
-
Dynamic_cast kann dein Programm ziemlich ausbremsen. Im allgemeinen solltest du sowiso versuchen ohne Casts auszukommen.
grüße
-
_et schrieb:
Vielen Dank!
Also ist dynamic_cast am sichersten - ist es auch am schnellsten oder wäre das static_cast? Sollte man denn wenn möglich (solange es funtioniert) dynamic_cast verwenden? Welche Typinformationen benutzt es denn zum casten?
Die Frage ist falsch gestellt. Wenn du in einer Klassenhierarchie downcasten willst oder musst, dann bleibt dir gar nichts anderes übrig, als einen dynamic_cast zu verwenden (sofern du den C-Cast nicht benutzt). Gleiches gilt für die anderen. Wie Jester schon sagte, hat jeder C++ Cast sein eigenes Anwendungsgebiet, du kannst mit einem static_cast halt kein const wegcasten oder downcasten. Geht net.
MfG
GPC
-
Okay, ich fragte unter anderem deshalb, weil ich gerade mit einem iterator hantiere und wenn ich das aktuelle Element in das nicht mehr Iterator gekapselte caste funktioniert praktisch alles (C-Cast, reinterpret_cast, static_cast, dynamic_cast). Für den Fall wäre dann static_cast am Sinnvollsten, der?
Kann ich denn einen Iterator benutzen ohne zu casten?
danke

-
GPC schrieb:
_et schrieb:
Vielen Dank!
Also ist dynamic_cast am sichersten - ist es auch am schnellsten oder wäre das static_cast? Sollte man denn wenn möglich (solange es funtioniert) dynamic_cast verwenden? Welche Typinformationen benutzt es denn zum casten?
Die Frage ist falsch gestellt. Wenn du in einer Klassenhierarchie downcasten willst oder musst, dann bleibt dir gar nichts anderes übrig, als einen dynamic_cast zu verwenden (sofern du den C-Cast nicht benutzt).
Das stimmt so nicht. In einfachen Hierarchien reicht auch ein static_cast. In solchen Hierarchien liegt der Unterschied zwischen static_cast und dynamic_cast in der Semantik. Der static_cast bedeutet: Hy Compiler, ich *weiß*, dass sich hinter meinem Base-Zeiger ein Derived-Objekt versteckt. Vertrau mir und gibt mir eine passende Referenz.
Ein dynamic_cast hingegen ist mehr: Lieber Compiler, schau doch mal bitte, ob sich hinter dem Base-Zeiger ein Derived-Objekt verbirgt. Falls ja, gib mir eine passende Referenz.Anders sieht es aus, bei Casts, die nicht eindeutig sind (virtuelle Basisklassen, Mehrfachvererbung). Der folgende Cross-Cast kann z.B. nur per dynamic_cast durchgeführt werden:
class B { public: virtual ~B() {} }; class C { public: virtual ~C() {} }; class D : public B, public C { }; int main() { B* b = new D; C* c = dynamic_cast<C*>(b); }Wie bereits gesagt wurde, verwendet der dynamic_cast Laufzeittypinformationen. Aus diesem Grund kann ein dynamic_cast (im Gegensatz zu einem static_cast) auch nur auf polymorphe Type verwendet werden.
Für Down-Cast halte ich mich an folgende Regeln:
* Der Default-Cast sollte ein dynamic_cast sein* In Ausnahmefällen, wo man genau weiß, dass der Cast korrekt ist und wo Performanz wichtig ist, verwendet man einen static_cast (Am Besten verpackt hinter einem Wrapper wie z.B. boost::polymorphic_cast)
* einen C-Cast sollte man nicht für Downcasts verwenden, da dieser sowohl wie ein reinterpret_cast (fehlende Klassendefinition), als auch wie ein static_cast (Klassendefinition bekannt) funktionieren kann.
-
HumeSikkins schrieb:
GPC schrieb:
_et schrieb:
Vielen Dank!
Also ist dynamic_cast am sichersten - ist es auch am schnellsten oder wäre das static_cast? Sollte man denn wenn möglich (solange es funtioniert) dynamic_cast verwenden? Welche Typinformationen benutzt es denn zum casten?
Die Frage ist falsch gestellt. Wenn du in einer Klassenhierarchie downcasten willst oder musst, dann bleibt dir gar nichts anderes übrig, als einen dynamic_cast zu verwenden (sofern du den C-Cast nicht benutzt).
Das stimmt so nicht. In einfachen Hierarchien reicht auch ein static_cast. In solchen Hierarchien liegt der Unterschied zwischen static_cast und dynamic_cast in der Semantik. Der static_cast bedeutet: Hy Compiler, ich *weiß*, dass sich hinter meinem Base-Zeiger ein Derived-Objekt versteckt. Vertrau mir und gibt mir eine passende Referenz.
Ein dynamic_cast hingegen ist mehr: Lieber Compiler, schau doch mal bitte, ob sich hinter dem Base-Zeiger ein Derived-Objekt verbirgt. Falls ja, gib mir eine passende Referenz.hmm... das wusste ich nicht. Dennoch bin ich über diese Möglichkeit nicht gerade erfreut, da sie die klare Abgenzung der Casts aufweicht. Trotzdem danke für die Info

-
_et schrieb:
...
Kann ich denn einen Iterator benutzen ohne zu casten?...Normalerweise schon. Allerdings geht es dabei weniger um den iterator als vielmehr um den Container, auf dem der iterator arbeitet.
Da Du in C++ (genauer in der STL) aber typisierte Container hast, brauchst Du eigentlich nicht zu casten. Im Gegensatz zu Java kann eben nicht alles Mögliche im Container stecken, sondern in einem vector<string> sind eben garantierterweise auch nur strings drin...Gib' doch mal das konkrete Beispiel.
Gruß,
Simon2.
-
@GPC
Die Fähigkeiten eines static_casts kann man sich recht einfach merken: er kann alle impliziten Konvertierungen umkehren. Daraus ergibt sich auch die Geschichte mit den down-casts.
Wenn du einen Zeiger base vom Typ Base und einen Zeiger derived vom Typ Derived hast und für die Zuweisung base = derived eine implizite (eindeutige) Umwandlung existiert (hier: upcast), dann kann die Gegenrichtung durch einen static_cast durchgeführt werden, also derived = static_cast<Derived*>(base).