2014-05-20 1 views
2

저는 C++ 예외 처리를 처음 접했습니다. 내 마음의 규칙은 다음 함수가 호출 종료 예외의 어떤 핸들러가 호출 체인 (함수 호출 스택)에서 발견되지 않는 경우생성자에서 발생한 예외 처리기는 무엇입니까?

  1. 점이다.
  2. 핸들러는 캐치 {} 블록이다.

그러나 다음 동작은 이해할 수 없습니다. X의 생성자에 던져 예외가 두 번 (. 또는 처리) 잡은 것 같다 :

#include <iostream> 
#include <exception> 
using namespace std; 

struct X { 
    X() try { throw exception(); } 
    catch (exception &e) { 
    cout << "Exception caught in constructor!" << endl; 
    } 
}; 

int main() { 

    try { 
    throw exception(); 
    } 
    catch (exception &e) { 
    cout << "Exception caught in function." << endl; 
    } 
    cout << "After Exception being caught in function" << endl; 

    try { 
    X x; 
    } 
    catch (exception &e) { 
    cout << "Why exception is caught again!" << endl; 
    } 

    return 0; 
} 

출력은

Exception caught in function. After Exception being caught in function Exception caught in constructor! Why exception is caught again!

질문 1입니다. 또는 생성자 다음에 catch() 블록이 생성자의 예외 처리기로 계산되지 않는 이유는 무엇입니까?

나는 try{} 블록에 X x;을 넣고 main()에 잡을 수없는 경우, 출력은 다음과 같습니다 우리가 할 때 호출는 기본 (종료 IS) 기능 :

Exception caught in function. After Exception being caught in function Exception caught in constructor! terminate called after throwing an instance of 'std::exception' what(): std::exception Aborted (core dumped)

질문 2 try 블록에 X x;이 없습니까?

+2

관련 항목 : http://stackoverflow.com/a/19687623/952747 – deepmax

+0

@MM. 고마워. 나는 수색했지만 그 질문을 놓쳤다. –

답변

1

당신 두 가지 예외가있다.

struct X { 
    X() try { throw exception(); } 
    catch (exception &e) { 
    cout << "Exception caught in constructor!" << endl; 
    } 
}; 

예외가 발생하면 생성자에서 처리합니다. BUT 개체를 아직 만들지 않았으므로 호출자 측에 개체가 없습니다. 호출자 은 생성되지 않은 객체 상황을 처리해야합니다.

두 번째 질문은 네입니다. [except.terminate] 표준. 이로 인해 std::terminate이 호출됩니다.

+0

http://stackoverflow.com/questions/23753821/why-do-we-need-a-function-try-block에서 다음 질문에 도움을주십시오. 답변 : http://stackoverflow.com/questions/19687146/an-exception-gets-thrown-twice-from-a-constructor-with-a-function-try-block/19687623#19687623 사용자 Kerrek SB는 다음과 같이 말합니다. "기능 - try-blocks을 사용하지 마십시오." –

4

으로 :

X() try { throw exception(); } 
catch (exception &e) { 
    cout << "Exception caught in constructor!" << endl; 
} 

X 객체가 완전히 구축되지 않는 등 캐치 예외를 무시할 수 없다 그것을 다시 던져해야합니다.

IMO, X에 ... (X() try : member(0) {} catch(exception&) {})을 던지면 더 분명합니다. 생성자 블록 안에 정상 시도 캐치를 사용할 수

참고 :

X() { 
    try { throw exception(); } 
    catch (exception &e) { 
     cout << "Exception caught in constructor!" << endl; 
    } 
} 

자연입니다.

+0

내 개인적인 견해로, 기본 클래스 생성자가 던질 때 더 좋은 예입니다. 실패한 멤버 초기화의 경우 복구 할 수 있지만 오브젝트의 불완전 초기화로 복구 ​​할 수는 없다고 주장 할 수 있습니다. – UldisK

관련 문제