In beiden Fällen ändern Sie, da Sie als Referenz abfangen, effektiv den Status des ursprünglichen Ausnahmeobjekts (das Sie sich als an einem magischen Speicherort befindlich vorstellen können, der beim anschließenden Abwickeln gültig bleibt - 0x98e7058
im folgenden Beispiel). Jedoch,
- Im ersten Fall wird der Aufruf zum Anhängen () wiedergegeben , da Sie mit
throw;
(das im Gegensatz throw err;
zum ursprünglichen Ausnahmeobjekt mit Ihren Änderungen an der "magischen Stelle" an 0x98e7058
) erneut wirft)
- Im zweiten Fall wird, da Sie etwas explizit werfen, eine Kopie von
err
erstellt und dann erneut geworfen (an einem anderen "magischen Ort" 0x98e70b0
- denn nach allem, was der Compiler weiß, err
könnte sich ein Objekt auf dem Stapel abwickeln, wie es e
war at 0xbfbce430
, nicht an der "magischen Stelle" at 0x98e7058
), so dass Sie während der Kopierkonstruktion einer Basisklasseninstanz abgeleitete klassenspezifische Daten verlieren .
Einfaches Programm, um zu veranschaulichen, was passiert:
#include <stdio.h>
struct MyErr {
MyErr() {
printf(" Base default constructor, this=%p\n", this);
}
MyErr(const MyErr& other) {
printf(" Base copy-constructor, this=%p from that=%p\n", this, &other);
}
virtual ~MyErr() {
printf(" Base destructor, this=%p\n", this);
}
};
struct MyErrDerived : public MyErr {
MyErrDerived() {
printf(" Derived default constructor, this=%p\n", this);
}
MyErrDerived(const MyErrDerived& other) {
printf(" Derived copy-constructor, this=%p from that=%p\n", this, &other);
}
virtual ~MyErrDerived() {
printf(" Derived destructor, this=%p\n", this);
}
};
int main() {
try {
try {
MyErrDerived e;
throw e;
} catch (MyErr& err) {
printf("A Inner catch, &err=%p\n", &err);
throw;
}
} catch (MyErr& err) {
printf("A Outer catch, &err=%p\n", &err);
}
printf("---\n");
try {
try {
MyErrDerived e;
throw e;
} catch (MyErr& err) {
printf("B Inner catch, &err=%p\n", &err);
throw err;
}
} catch (MyErr& err) {
printf("B Outer catch, &err=%p\n", &err);
}
return 0;
}
Ergebnis:
Base default constructor, this=0xbfbce430
Derived default constructor, this=0xbfbce430
Base default constructor, this=0x98e7058
Derived copy-constructor, this=0x98e7058 from that=0xbfbce430
Derived destructor, this=0xbfbce430
Base destructor, this=0xbfbce430
A Inner catch, &err=0x98e7058
A Outer catch, &err=0x98e7058
Derived destructor, this=0x98e7058
Base destructor, this=0x98e7058
---
Base default constructor, this=0xbfbce430
Derived default constructor, this=0xbfbce430
Base default constructor, this=0x98e7058
Derived copy-constructor, this=0x98e7058 from that=0xbfbce430
Derived destructor, this=0xbfbce430
Base destructor, this=0xbfbce430
B Inner catch, &err=0x98e7058
Base copy-constructor, this=0x98e70b0 from that=0x98e7058
Derived destructor, this=0x98e7058
Base destructor, this=0x98e7058
B Outer catch, &err=0x98e70b0
Base destructor, this=0x98e70b0
Siehe auch: