Trong cả hai trường hợp, vì bạn nắm bắt bằng cách tham chiếu, bạn đang thay đổi hiệu quả trạng thái của đối tượng ngoại lệ ban đầu (mà bạn có thể coi là nằm trong một vị trí bộ nhớ ma thuật sẽ vẫn có giá trị trong lần mở tua tiếp theo - 0x98e7058
trong ví dụ bên dưới). Tuy nhiên,
- Trong trường hợp đầu tiên, vì bạn rethrow với
throw;
(mà, không giống như throw err;
, giữ nguyên đối tượng ngoại lệ ban đầu, với các sửa đổi của bạn, trong "vị trí huyền diệu" tại 0x98e7058
) sẽ phản ánh lệnh gọi append ()
- Trong trường hợp thứ hai, vì bạn ném một thứ gì đó một cách rõ ràng, một bản sao của
err
sẽ được tạo sau đó được ném lại (tại một "vị trí phép thuật" khác 0x98e70b0
- bởi vì đối với tất cả những gì mà trình biên dịch biết err
có thể là một đối tượng trên ngăn xếp sắp được giải nén, như e
là tại 0xbfbce430
, không phải ở "vị trí huyền diệu" tại 0x98e7058
), vì vậy bạn sẽ mất dữ liệu dành riêng cho lớp dẫn xuất trong quá trình sao chép xây dựng một cá thể lớp cơ sở.
Chương trình đơn giản để minh họa những gì đang xảy ra:
#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;
}
Kết quả:
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
Cũng thấy: