catch 内の次の append() により、再スローされた例外で、呼び出された append() の効果を確認できますか?
try {
mayThrowMyErr();
} catch (myErr &err) {
err.append("Add to my message here");
throw; // Does the rethrow exception reflect the call to append()?
}
同様に、このように書き直すと、実際の例外が myErr によって派生した場合にビット スライスが発生しますか?
try {
mayThrowObjectDerivedFromMyErr();
} catch (myErr &err) {
err.append("Add to my message's base class here");
throw err; // Do I lose the derived class exception and only get myErr?
}
ベストアンサー1
どちらの場合も、参照でキャッチするので、元の例外オブジェクトの状態を事実上変更することになります(これは、その後の巻き戻し中に有効なままになる魔法のメモリ位置--0x98e7058
下の例では、
- 最初のケースでは、 で再スローするため
throw;
( とは異なりthrow err;
、 の「魔法の場所」にある元の例外オブジェクトが、変更を加えて保持されます0x98e7058
)、意思append() の呼び出しを反映する - 2番目のケースでは、明示的に何かを投げるので、コピーの
err
が作成され、その後、新たにスローされます (異なる「魔法の場所」で0x98e70b0
-- コンパイラーが認識している限りでは、は の「魔法の場所」ではなく の のようerr
に、スタック上に巻き戻されようとしているオブジェクトである可能性があるため)。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
以下も参照: