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 le dossier un emplacement mémoire magique qui restera valide lors du déroulement ultérieur -- 0x98e7058
dans l'exemple ci-dessous). Cependant,
- Dans le premier cas, puisque vous relancez avec
throw;
(qui, contrairement à throw err;
préserve l'objet d'exception original, avec vos modifications, dans ledit "emplacement magique" à 0x98e7058
) sera reflète l'appel à append()
- Dans le second cas, puisque vous lancez quelque chose de manière explicite, un fichier copie de
err
sera créé puis relancé (à un autre "endroit magique"). 0x98e70b0
-- parce que pour autant que le compilateur sache err
pourrait être un objet sur la pile sur le point d'être déroulé, comme e
était à 0xbfbce430
et non dans le "lieu magique" à 0x98e7058
), donc vous perdrez les données spécifiques aux classes dérivées lors de la copie-construction d'une instance de la 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
Voir aussi :