В обох випадках, оскільки ви переймаєтесь посиланням, ви ефективно змінюєте стан оригінального об'єкта виключення (який ви можете вважати таким, що знаходиться у магічному місці пам'яті, яке залишатиметься дійсним під час наступного розкручування - 0x98e7058
у прикладі нижче). Однак,
- У першому випадку, оскільки ви повторно скидаєте
throw;
(який, на відміну від цього throw err;
, зберігає оригінальний об'єкт виключення, з вашими модифікаціями, у вказаному "магічному розташуванні" на 0x98e7058
) буде відображати заклик додати ()
- У другому випадку, так як ви кидаєте що - то явно, копія з
err
буде створено потім викинутий заново (в іншому «чарівному місці» 0x98e70b0
- тому що для всіх компілятор знає , err
може бути об'єкт в стеці близько бути unwinded, як e
було at 0xbfbce430
, а не в "магічному розташуванні" at 0x98e7058
), тож ви втратите дані, специфічні для класу, під час створення копії екземпляра базового класу.
Проста програма для ілюстрації того, що відбувається:
#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;
}
Результат:
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
Також дивіться: