원래 예외의 재발행에 대한 C ++ 예외 질문
catch의 다음 append ()로 인해 다시 throw 된 예외가 호출되는 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?
}
참조로 잡기 때문에 두 경우 모두, 당신은 효과적으로 (당신이 거주하는 등 생각할 수있는 원래의 예외 객체의 상태를 변경하는 후속 푸는 동안 유효하게 유지되는 마법의 메모리 위치 - 0x98e7058
예 아래에있는을). 하나,
- 첫 번째 경우에 다시 던지기 때문에
throw;
(과 달리throw err;
원래 예외 객체를 수정하여에서 언급 한 "마법의 위치"에서0x98e7058
) 는 append () 호출을 반영합니다. - 명시 적으로 뭔가를 던져 이후 두 번째 경우,하는 사본 의
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
참조 :
This question is rather old and has an answer appropriate to the time it was asked. However, I just want to add a note on how to do proper exception handling since C++11 and I believe this corresponds very well to what you were trying to achieve with your append function:
Use std::nested_exception
and std::throw_with_nested
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace! You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
Yes, rethrowing rethrows the original exception object, which you have modified by a reference. You can also catch a base class reference, modify by it and still be able to rethrow the original derived exception type by throw;
.
for first question, yes.
but for second, refer to Vlad answer. you will need to carefully design your exception object to handle copy ctor. by convention, base class doesn't recognize its child so you will most likely lose the additional data carried by derived class.
참고URL : https://stackoverflow.com/questions/2360597/c-exceptions-questions-on-rethrow-of-original-exception
'Programming' 카테고리의 다른 글
문자, 코드 포인트, 글리프 및 자소의 차이점은 무엇입니까? (0) | 2020.08.13 |
---|---|
iPhone의 "홈 화면에 추가"에 대한 Javascript? (0) | 2020.08.13 |
Mercurial 파일의 개정 내역을 보는 방법은 무엇입니까? (0) | 2020.08.13 |
오류 :이 Android SDK에는 Android Developer Toolkit 버전 22.6.1 이상이 필요합니다. (0) | 2020.08.13 |
람다 식 대 메서드 참조 (0) | 2020.08.13 |