Ich habe über das Internet und diesen Thread nach einem kompletten gesucht Antwort auf diese Situation Ich bin konfrontiert. Ich habe gelesen, dass das Werfen klug ist Zeiger auf Objekte sind nicht sehr schlau. Ich will nur verstehen warum ist das passiert. Ich werde die Situation erklären. Stellen wir uns das vor einfache Hierarchie:
%Vor%Und lassen Sie uns diesen Testcode überprüfen:
%Vor%Alles wird kompiliert, aber in der Laufzeit wird der zweite try-catch nicht sein hingerichtet. Kann mir jemand erklären warum? Besonders wenn Codezeilen wie das funktioniert in der Laufzeit einwandfrei.
%Vor%Ich verstehe, dass das Problem darin besteht, dass SPFooInherited nicht von SPFoo erbt (obwohl FooInherited von Foo erbt), aber es würde gerne wissen, was der Compiler / RTE anders macht als das Funktionsaufrufbeispiel, wenn eine Ausnahme abgefangen wird die Situation nicht lösen zu können. Liegt es daran, dass der Parameter catch nicht mit einem Parameter für den Funktionsaufruf übereinstimmt? Warum Foo & amp; funktioniert und SPFoo nicht?
Vielen Dank im Voraus.
Grüße, Iker.
Wie Sie in Ihrer Frage gesagt haben, ist SPFooInherited
keine Unterklasse von SPFoo
. Dies bedeutet, dass catch(SPFoo const&)
keine Instanzen von SPFooInherited
abfängt. Auf der anderen Seite wird FooInherited
von Foo
geerbt, und so wird catch(Foo const&)
Instanzen von FooInherited
fangen.
Um dies zu verstehen, benötigen Sie kein spezielles Verständnis des Compilers oder der Laufzeitumgebung. Es ist einfach ein Teil der Sprache.
Der Grund für den Aufruf der Funktion ist, dass tr1::shared_ptr
einen nicht-expliziten Konstruktor hat, der eine implizite Konvertierung an Funktionsaufruf-Sites ermöglicht.
Das heißt: tr1::shared_ptr
hat den folgenden Konstruktor:
Dies ermöglicht, dass shared_ptr
aus einem anderen gemeinsam genutzten Zeigertyp erstellt wird. Die Implementierung dieses Konstruktors basiert auf der impliziten Konvertierung von FooInherited*
nach Foo*
, um den Zeiger tatsächlich in SPFooInherited
in SPFoo
zu speichern. Wenn diese implizite Konvertierung nicht vorhanden ist, wird der Code nicht kompiliert, und daher werden unsafe Konvertierungen zwischen shared_ptr
s zu nicht verwandten Typen nicht auftreten.
Der grundlegende Unterschied zwischen dem Funktionsaufruf und dem Catch besteht darin, dass implizite Konvertierungen bei der Initialisierung von Funktionsargumenten auftreten, ein Catch jedoch nur einem einzelnen Typ entsprechen kann ( FooInherited
ist-a Foo
, damit er übereinstimmt ).
Weil SPFoo
keine Unterklasse von SPFooInherited
ist. catch
Blöcke fangen nur Objekte ein, die sich in ihrer Fangliste befinden, oder eine öffentliche Kindklasse von dem, was sich in ihrer Fangliste befindet. FooInherited
macht inhertit von Foo
, so dass du mit Foo
auch FooInherited
fangen kannst. SPFoo
und SPFooInherited
sind völlig verschiedene und nicht verwandte Klassen.
Tags und Links c++ exception smart-pointers