(* 1) erzeugt einen Fehler und ich verstehe warum. (* 2) Kompiliert gut, aber warum? Und, solange es kompiliert und annimmt, dass B
einige Attribute enthält, was passiert, wenn ich a_ref
auf B&
umwandle und dann versuche, auf die Attribute zuzugreifen? Ich denke, dass ich einen Laufzeitfehler oder etwas haben werde.
Also, wie ich sehen kann, gibt es eine Situation, die zum Absturz führt, und es gibt keine Wege, sie zu vermeiden, im Gegensatz zu dynamic_cast
, wo man das Ergebnis des Castings auf null überprüfen oder Code in ein try-catch
setzen kann. Region. Wie muss ich mit einer solchen Situation umgehen, in der ich Referenzen werfen und sicher sein muss, dass ich wirklich die richtigen Referenzen bekomme.
Ab Standard n3337 Entwurf 5.2.9 / 2
Ein Lvalue vom Typ "cv1 B", wobei B ein Klassentyp ist, kann umgewandelt werden, um "reference to cv2 D" einzugeben, wobei D eine Klasse ist abgeleitet (Klausel 10) von B, wenn eine gültige Standardkonvertierung von "Zeiger nach D" nach "Zeiger nach B" existiert (4.10), cv2 ist die gleiche cv-Qualifikation wie cv-qualification oder cv-qualification, cv1 und B ist weder eine virtuelle Basisklasse von D noch eine Basisklasse einer virtuellen Basisklasse von D.
In Ihrem Fall:
B
ist eine Klasse, die von A
abgeleitet ist, beide sind nicht konstant, und die Konvertierung von A*
nach B*
ist erlaubt, A
ist keine virtuelle Basisklasse von D
.
Dies ist einer der Gründe, warum ich boost::polymorphic_downcast
( doc <) verwende / a>) - im Debug verwendet es dynamic_cast
gefolgt von assert und in release ist es static_cast
, also keine Performance-Treffer.
static_cast<>
prüft nur, ob die Typen kompatibel sind
Falls 1 Typen nicht direkt kompatibel sind, da das re kein Operator ist, um die Kopie Beziehung zwischen A und B
zu beschreiben Im Fall 2 ist der Cast ein Referenz-Cast und soweit der Compiler betroffen ist, kann A*
auf B*
geworfen werden, da sie kompatibel sind. Der Compiler wird nicht wissen, was der Zeiger a_ref
enthält, deshalb können Sie ihn verwenden. dynamic_cast<>
prüft die Klasse, auf die der Zeiger zeigt.
(* 2) kompiliert gut, aber warum?
Im Allgemeinen können Sie den dynamischen Typ nicht statisch überprüfen. und static_cast
führt keine dynamische Typprüfung durch. Es erlaubt jede Konvertierung, die möglicherweise gemäß den statischen Typen gültig ist, einschließlich Konvertierungen, die gemäß den dynamischen Typen nicht gültig sind.
Was passiert, wenn ich a_ref auf B & amp; und dann versuchen, auf die Attribute zuzugreifen?
Undefiniertes Verhalten. Wenn Sie static_cast
verwenden, müssen Sie sicherstellen, dass die Konvertierung gültig ist.
Wie muss ich mit einer solchen Situation umgehen, in der ich Referenzen referenzieren muss und sicher sein muss, dass ich wirklich die richtigen Referenzen bekomme?
Verwenden Sie für polymorphe Typen dynamic_cast
. Auf eine Referenz angewendet, wird std::bad_cast
ausgegeben, wenn die Konvertierung nicht gültig ist.
Für nicht-polymorphe Typen sind Sie allein.
Tags und Links c++ static-cast