Fehler: kann nicht dynamic_cast ... (Ziel ist nicht Zeiger oder Referenz)

8

Ich lerne Ausnahmebehandlung in C ++ und lief auf ein Problem. Hier ist der Code:

%Vor%

Also dachte ich, der try catch würde die Ausführung der Funktion erlauben und mir den Inhalt der Ausnahme anzeigen, aber mein Compiler kompiliert sie nicht. Ich verwende Codeblock mit GNU GCC. Bitte helfen Sie mir und zeigen Sie mir, was ich tun muss, damit der Code wie gewünscht ausgeführt wird. vielen Dank.

    
focusHard 16.06.2013, 02:48
quelle

4 Antworten

18

dynamic_cast kann nur auf einen Zeigerwert oder eine Referenz umgewandelt werden, was genau der Fehler ist, den Sie erhalten.

Ab $ 5.2.7 / 1 des C ++ Standards.

  

Das Ergebnis des Ausdrucks dynamic_cast & lt; T & gt; (v) ist das Ergebnis der Umwandlung des Ausdrucks v in den Typ T. T soll ein Zeiger oder Verweis auf einen vollständigen Klassentyp oder "Zeiger auf cv void" sein.

Damit dynamic_cast eine Ausnahme auslöst, wenn das Objekt nicht konvertiert werden kann, müssen Sie eine Referenz erstellen. Ändern Sie es wie folgt:

%Vor%

Wie Johnsyweb darauf hingewiesen hat, dass dynamic_cast immer std::bad_cast wenn die Konvertierung fehlschlägt. Obwohl std::bad_cast von std::exception abgeleitet ist, ist es immer eine gute Idee, die Ausnahme zu verwenden, die der erwarteten Fehlerbedingung am besten entspricht. Dadurch wird verhindert, dass andere Fehler versehentlich als fehlgeschlagener Cast interpretiert werden.

Um dies auf Ihr Beispiel anzuwenden, sieht es möglicherweise wie der folgende Code aus.

%Vor%

[Es wird dringend davon abgeraten, Dinge wie using namespace std; zu tun, da dies zu Konflikten mit Bezeichnern im globalen Namespace führen kann. Ich habe es im obigen Beispiel entfernt.]

    
Captain Obvlious 16.06.2013 02:56
quelle
5

Ihr Problem besteht nicht in der Ausnahmebehandlung , sondern in Ihrer dynamischen Besetzung :

%Vor%

dynamic_cast konvertiert Zeiger und Referenzen sicher zu class es und nicht zu Instanzen .

So könnten Sie tun:

%Vor%

... welches immer fehlschlägt und ein std::bad_cast wirft Ausnahme.

Sie sollten den spezifischsten Typ von exception , den Sie erwarten, abfangen und seit den empfohlenen Weg zu catch finden Referenz , sollten Sie bevorzugen:

%Vor%

Weitere Informationen: dynamic_cast-Konvertierung auf cppreference.com .

    
Johnsyweb 16.06.2013 02:57
quelle
3

Sie erhalten einen Compilerfehler, weil Ihr dynamic_cast nicht auf Zeiger oder Referenz steht.
Ändere es zu:

%Vor%

... und Sie bekommen die richtige Ausnahme geworfen.

Nebenbei bemerkt: Intelligente Compiler wie g ++ würden auch warnen:
Warnung: dynamic_cast für ein Objekt (hier a ) kann niemals erfolgreich sein .

Es ist also besser, diesen Code zum Spielen zu begrenzen. Im Produktionsqualitätscode sollte dynamic_cast nur für Zeiger / Referenzen ausgeführt werden.

    
iammilind 16.06.2013 02:56
quelle
0

Ich habe gerade den gleichen Fehler behandelt, aber in meinem Fall ging ich von einem Zeiger zu einem Zeiger, so dass die anderen Antworten hier nicht zutreffen. Meine Fehlermeldung war jedoch etwas anders: error: cannot dynamic_cast 'f()' (of type 'class B*') to type 'class A*' (target is not pointer or reference to complete type) .

Die Ursache in meinem Fall war viel einfacher und banaler.

Beachten Sie, dass am Ende hinzugefügt wird, um den Typ zu vervollständigen. Dies veranlasste mich zu erinnern, dass ich die Header-Datei für meine Klasse, die ich verwendete, nicht einschloss. Es war kein unbekanntes Symbol, weil A* mit class A; in der Header-Datei vorwärts deklariert wurde, was dazu führte, dass es existierte, aber nicht vollständig war, daher der Fehler.

Die Lösung in meinem Fall war, die Header-Datei für die Klasse, in die ich gegossen habe, einzuschließen.

Dies ist nicht das Problem des Fragestellers oben, aber wie ich an meinem Fall sehen kann, kann derselbe Fehlertyp auftreten.

    
Aaron 16.08.2016 18:50
quelle