의 유형을 찾아 내가 가진 말 디버그 정보가 없습니다. 무엇이 던져 졌는지 찾아내는 방법이 있습니까? 그렇지 않으면 관련된 데이터를 얻는 방법이 있습니까?C++ 잡힌 기본 예외
throw myStupidCustomString("here is some really useful information");
하지만 ++ 2008이 중요한 경우 MSVC에서 작업
...
을 잡으면 나는 결코 알지 못할 것입니다 : 그들은 일을 할 수 .
의 유형을 찾아 내가 가진 말 디버그 정보가 없습니다. 무엇이 던져 졌는지 찾아내는 방법이 있습니까? 그렇지 않으면 관련된 데이터를 얻는 방법이 있습니까?C++ 잡힌 기본 예외
throw myStupidCustomString("here is some really useful information");
하지만 ++ 2008이 중요한 경우 MSVC에서 작업
...
을 잡으면 나는 결코 알지 못할 것입니다 : 그들은 일을 할 수 .
C++은 정적으로 입력되므로 알려진 유형을 catch해야합니다. 그러나 호출 한 지점에서 알 수없는 예외 유형을 처리하는 외부 함수 (또는 함수 집합)를 호출 할 수 있습니다. 이러한 핸들러에 알려진 유형이 모두있는 경우이를 동적으로 시도하도록 등록 할 수 있습니다.
struct myStupidCustomString {
myStupidCustomString(char const *what) : what (what) {}
char const *what;
};
void throws() {
throw myStupidCustomString("here is some really useful information");
}
// The external library can provide a function, or you can provide a wrapper, which
// extracts information from "unknown" exception types.
std::string extract_from_unknown_external_exception() {
try { throw; }
catch (myStupidCustomString &e) {
return e.what;
}
catch (...) {
throw; // Rethrow original exception.
}
}
:
void example() {
try { throws(); }
catch (...) {
try {
std::string extracted = extract_from_unknown_external_exception();
std::cout << "extracted: " << extracted << '\n';
}
catch (...) {
// Chain handlers for other types; e.g. exception types from other libraries.
// Or do something generic for the unknown exception.
// Or rethrow the original unknown exception:
throw;
}
}
}
Handler chain : 당신이 구현 세부 사항을 알고있는 경우
는typedef std::string Extract();
std::vector<Extract*> chain (1, &extract_from_unknown_external_exception);
// Chain would normally be initialized using whatever scheme you prefer for
// initializing global objects.
// A list or other container (including a manual linked list that doesn't
// require dynamic allocation) may be more appropriate, depending on how you
// want to register and unregister handlers.
std::string process_chain() {
for (std::vector<Extract*>::iterator x = chain.begin(); x != chain.end(); ++x) {
try {
return (*x)();
}
catch (...) {} // That handler couldn't handle it. Proceed to next.
}
throw; // None could handle it, rethrow original exception.
}
void example() {
try { throws(); }
catch (...) {
try {
std::string extracted = process_chain();
std::cout << "extracted: " << extracted << '\n';
}
catch (...) {
throw; // Rethrow unknown exception, or otherwise handle it.
}
}
}
마지막으로, 당신은 당신의 구현을 노출하는 추가 정보를 추출하는 사람들을 사용할 수 있습니다. C++ 0x는 몇 가지 세부 사항을 이식성있는 방식으로 노출합니다. std :: exception_ptr을 보라.
표준 C++에서는 사용할 수 없습니다. 이러한 예외는 매우 예외적 인 것으로 간주하고 나쁜 예외가 있다는 사실을 기록하여 처리 한 다음 프로그램을 종료하려고 시도하지만 여전히 할 수 있습니다.
운이 좋다면 모든 데이터를 저장할 수 있습니다.
당신은 당신이 알고있는 희망 단지 수 (catch(...)
블록에, 나는 cource의 의미) C++의 예외의 종류를 알 수있는 방법이 없습니다 정확히 externalLibrary::doSomething();
당신이 그것을 작성한 경우, 수행, 또는 귀하의 경우처럼, 당신은 단지 externalLibrary::doSomething();
에 대한 훌륭한 문서가 있다는 것을 희망 할 수 있습니다. 모든 훌륭한 라이브러리에는 상세한 문서가 있습니다.
예외에 대한 자세한 내용은 필자의 경험에 비추어 볼 때 매개 변수에 대한 일반적인 문서가 아닙니다. 그렇다면 표준 가능성을 테스트해야 할 것입니다 ... 시스템 예외는 무엇입니까? –
"시스템 예외는 무엇입니까?" 그들이 C++ 프로그램에서 잡힐 수 있는지 나는 모른다 :? 또한, 내가 사용한 라이브러리의 대부분은 문서화 된 자체적 인 예외 계층 구조를 가지고 있습니다. 그러나 물론 이것은 모든 도서관에 그런 것이 있다는 것을 의미하지는 않습니다. 또한 C lib 인 경우 예외가 발생하지 않습니다. –
나는 null-ptr 액세스, div/0 등과 같은 것들을 잡는 특별한 방법이 없다는 것을 의미합니까? 제 3 자 lib가 버그가있는 그런 문제를 잡을 방법이 있다고 생각했습니다. –
gcc 또는 CLANG를 사용하면 트릭을 사용하여 '알 수없는'예외 유형을 알 수 있습니다. 이것이 비표준임을 명심하십시오!
#include <cstdlib>
#include <iostream>
#include <cxxabi.h>
using namespace __cxxabiv1;
std::string util_demangle(std::string to_demangle)
{
int status = 0;
char * buff = __cxxabiv1::__cxa_demangle(to_demangle.c_str(), NULL, NULL, &status);
std::string demangled = buff;
std::free(buff);
return demangled;
}
struct MyCustomClass
{};
int main(int argc, char * argv[])
{
try
{
throw MyCustomClass();
}
catch(...)
{
std::cout << "\nUnknown exception type: '" << util_demangle(__cxa_current_exception_type()->name()) << "'" << std::endl;
}
return(0);
}
Omg. 나는 너에게 지금 키스 할 수있어. 감사합니다 <3 –
안녕하세요, 저는 이것이 훌륭한 대답이라고 생각합니다.그러나이 표준 작동 여부에 대한 표준 정보는 찾을 수 없습니다. 나는 그것을 테스트했고 VisualStudio, GCC 및 LLVM에서 모두 작동하지만 완전히 이유는 모르겠습니다. 그래서 새로운'try {} catch() {}'블록을 입력해도 어떤 식 으로든 현재의 예외에는 영향을 미치지 않습니까? 감사! – NHDaly
왜 작동하지 않을지 잘 모르겠다 고 생각합니다. try 블록을 사용하면 현재 예외에는 영향을주지 않지만 두 번 확인하고 싶을 것입니다. – NHDaly