Dans les deux cas, puisque vous attrapez par référence, vous modifiez effectivement l'état de l'objet d'exception d'origine (que vous pouvez considérer comme résidant dans un emplacement de mémoire magique qui restera valide lors du déroulement suivant - 0x98e7058
dans l'exemple ci-dessous). cependant,
- Dans le premier cas, puisque vous rethrow avec
throw;
(qui, contrairement throw err;
, préserve l'objet d'exception d' origine, avec vos modifications, dans ledit « lieu magique » à 0x98e7058
) va tenir compte de l'appel à append ()
- Dans le second cas, puisque vous lancez quelque chose explicitement, une copie de
err
sera créée puis lancée à nouveau (à un autre "emplacement magique" 0x98e70b0
- car pour tout ce que le compilateur sait, il err
pourrait y avoir un objet sur la pile sur le point d'être déroulé, comme ce e
fut at 0xbfbce430
, pas dans "l'emplacement magique" at 0x98e7058
), vous perdrez donc les données spécifiques à la classe dérivée lors de la construction de copie d'une instance de classe de base.
Programme simple pour illustrer ce qui se passe:
#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;
}
Résultat:
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
Regarde aussi: