どちらの場合も、参照でキャッチするため、元の例外オブジェクトの状態を効果的に変更します(これは、次の巻き戻し中も有効な魔法のメモリロケーションにあると考えることができます- 0x98e7058
以下の例で)。しかしながら、
- あなたが再スローするので最初のケースでは、
throw;
(とは違った、throw err;
、で言った「魔法の場所」で、あなたの修正を加えて、オリジナルの例外オブジェクトを保持する0x98e7058
)します(アペンドへの呼び出しを反映)
- あなたが明示的に何かを投げるので、後者の場合は、コピーのは、
err
その後、別の「魔法の場所」で(新たに投げ作成される0x98e70b0
すべてのコンパイラを知っているので- err
のように、unwindedされようと、スタック上のオブジェクト可能性がありe
ましたで0xbfbce430
、「魔法の場所」ではありません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
こちらもご覧ください: