2012-10-21 9 views
8

Ich möchte wissen, wie das Ausnahmeobjekt erstellt wird? und warum der Handler-Funktionsparameter eine nicht-konstante Referenz sein kann?Lebensdauer des Ausnahmeobjekts

Zum Beispiel:

class E{ 
    public: 
    const char * error; 
    E(const char* arg):error(arg){ 
    cout << "Constructor of E(): ";} 

    E(const E& m){ 
     cout << "Copy constructor E(E& m): " ; 
     error=m.error; 
    } 
}; 



int main(){ 
try{ 
    throw E("Out of memory"); 

} 
catch(E& e){cout << e.error;} 

} 

Ausgang: Constructor von E(): Nicht genügend Arbeitsspeicher

so habe ich throw E("out of memory") und E("out of memory") ist nur ein temporäres Objekt und kein Objekt wurde erstellt, außer E("out of memory"), da kein Kopierkonstruktor aufgerufen wurde. Obwohl diese nur ein temporäres Objekt ist, habe ich einen Handler, der eine nicht-konstante Referenz verwendet.

Können Sie mir erklären, warum das möglich ist?

+1

'weil kein Kopierkonstruktor aufgerufen wurde. Obwohl dieses E ("out of memory") nur ein temporäres Objekt ist, habe ich einen Handler, der eine nicht-konstante Referenz nimmt - http://en.wikipedia.org/wiki/Copy_elision –

+0

@skwllsp: so Dies liegt an der Optimierung. Bedeutet dies, dass das temporäre Objekt nicht erstellt wurde und das Argument direkt an das Ausnahmeobjekt übergeben wurde? – AlexDan

Antwort

10

möchten Sie wissen, wie das Ausnahmeobjekt erstellt wird?

Wenn Sie dies tun:

throw E("Out of memory"); 

Sie ein Objekt erstellen (vom Typ E) vor Ort. Die Prozesse des Werfens kopieren dieses Objekt an einen privaten Speicherort, der nicht durch den Standard definiert ist. Daher muss das Objekt, das geworfen wird, kopierbar sein.

Hinweis: Der Compiler darf die Kopie optimieren und direkt am privaten Ort erstellen. Die Tatsache, dass es nicht kopiert wird, liegt daran, dass der Compiler die Kopie optimiert hat (also nicht mehr lokal ist). Versuchen Sie, den Kopierkonstruktor als privat zu definieren, und jetzt wird die Kompilierung fehlschlagen.

und warum der Handler-Funktionsparameter kann eine nicht-const Referenz sein?

Wenn Sie das Objekt zu fangen:

catch(E& e) 

Sie sind an dem privaten Standort für das Objekt einen Verweis bekommen es kopiert wurde. Es ist kein konstanter (oder temporärer) Wert, so dass Sie einen normalen Verweis darauf haben können.

+0

Wie lange ist diese Fangreferenz gut? – xaxxon

+0

@xaxxon: http://stackoverflow.com/a/1654187/14065 –