2012-04-04 6 views
2
#include <iostream> 
#include <exception> 
using namespace std; 


class myexception: public exception 
{ 
    virtual const char* what() const throw() 
    { 
    return "My exception happened"; 
    } 
}; 

int main() 
{ 
    try 
    { 
    myexception myex; 
    printf("addr1:%x\n",&myex); 
    throw myex; 
    } 
    catch (exception& e) 
    { 
    printf("addr2:%x\n",&e); 
    cout << e.what() << endl; 
    } 
    return 0; 
} 

Ausgabe dieses Programms:

addr1:6d78c020 
addr2:20a1080 
My exception happened 

Frage: Sehen Sie addr1 und addr2 verschieden sind, eine Idee, warum?C++ - Ausnahmebehandlung durch Verweis übergeben: geworfene Adresse unterscheidet sich von abgefangener Adresse?

Antwort

6

Wenn eine Ausnahme ausgelöst wird, wird eine Kopie erstellt. Sie sehen die Adresse dieser Kopie.

(Wie wird die Handler Ausnahme die gleiche Adresse haben? Wenn Sie warf, verlassen Sie den Block die Ausnahme enthält, so hörte es auf zu existieren. Man kann nicht etwas zuzugreifen, die nicht existiert.)

+0

Kopie wird nur im Falle von Pass-by-Wert richtig gemacht? , aber hier habe ich den Code eingefügt, der Pass-by-Reference verwendet. –

+2

Der 'throw' macht die Kopie aus. Sie fangen eine Referenz, aber es ist ein Verweis auf die Kopie, die von 'throw' gemacht wurde. –

+0

in C++ - Objekten werden erstellt, indem der entsprechende Konstruktor entweder als Standard oder als Kopierkonstruktor aufgerufen wird. Stimmst du mir zu? Im obigen Beispiel ist addr2 ein neues Objekt, das durch den Aufruf des Kopierkonstruktors erstellt wurde. Meine Frage ist, Kopierkonstruktor wird nur für den Vorübergehender-Wert nicht für den Vorübergehender-Verweis aufgerufen. –

1

Das macht Sinn. Die Ausnahme wird kopiert, wenn sie ausgelöst wird, sodass sie das Verlassen des Stapelrahmens ihres Ursprungs überleben kann. Sobald diese Ausnahme den {}-Block, aus dem sie stammt, verlässt, wird dieser Stack-Frame gelöscht und alle Locals in ihm sind verschwunden. Also muss es kopiert werden.

+0

Ich verstehe diesen Punkt, aber meine Frage ist völlig anders als Ihre Antwort. Im obigen Programm sehen Sie, wie der Kopierkonstruktor aufgerufen wird (wenn Sie einen Kopierkonstruktor schreiben, dann können Sie ihn sehen), der eine separate Kopie eines Objekts erstellt. Tatsächlich wird der Kopierkonstruktor nur für temporäre Objekte aufgerufen, z. B. für "pass-by-value". –

+2

@SamJ: * Aber tatsächlich kopieren Konstruktor wird nur für temporäre Objekte wie Pass-by-Value. * Das ist eine ziemlich Aussage, und ein Fehler. Kopien können für andere Dinge als temporäre Objekte erstellt werden und in einigen Fällen werden temporäre Objekte nicht das Ergebnis von Kopien sein oder selbst kopiert werden. –

Verwandte Themen