c ++ static_cast und Referenzen

8
%Vor%

(* 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.

    
fogbit 30.10.2013, 13:03
quelle

4 Antworten

7

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 .

    
ForEveR 30.10.2013, 13:05
quelle
4

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.

    
Johny 30.10.2013 13:08
quelle
3

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.

    
Raxvan 30.10.2013 13:07
quelle
1
  

(* 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.

    
Mike Seymour 30.10.2013 13:16
quelle

Tags und Links