In entrambi i casi, poiché catturi per riferimento, stai effettivamente alterando lo stato dell'oggetto eccezione originale (che puoi pensare come residente in una posizione di memoria magica che rimarrà valida durante il successivo svolgimento - 0x98e7058
nell'esempio sotto). Però,
- Nel primo caso, dal momento che si rigenerare con
throw;
(che, a differenza throw err;
, conserva l'oggetto eccezione originale, con le modifiche, in detto "luogo magico" a 0x98e7058
) si riflettono la chiamata a append ()
- Nel secondo caso, dal momento che lanci qualcosa in modo esplicito, verrà creata una copia di
err
verrà quindi lanciata di nuovo (in una diversa "posizione magica" 0x98e70b0
- perché per quanto ne sa il compilatore err
potrebbe essere un oggetto sullo stack in procinto di essere srotolato, come e
era at 0xbfbce430
, non nella "posizione magica" at 0x98e7058
), quindi perderai i dati specifici della classe derivata durante la costruzione della copia di un'istanza della classe base.
Semplice programma per illustrare cosa sta succedendo:
#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;
}
Risultato:
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
Vedi anche: