2011-09-19 2 views
2

내가 좋아하는 코드를 많이 includs 대규모 프로젝트에 코드를 읽을 시도 ++ . "예외 e"와 같은 것이 아닙니다.는 -catch

이렇게하면 조금 걱정됩니다. 이 방법이 좋든 안전한가요? 덕분에 .

+0

나는이 종류의 와일드 카드로 상상하는 것 : 더 나은이 정리를 자동화하는 RAII classes 소위 사용 하는가? 다른 사람이 그것을 확인할 수 있습니까? – MGZero

+0

@MGZero 예, 와일드 카드로 모든 것을 잡습니다. –

+0

[C++ catch catch practices] 중복 (0120) –

답변

11

아니요, 이것은 끔찍한 사례입니다.

catch(...)이라면 무엇을 잡았는지 알 수 없습니다. 모든 C++ 예외를 포착합니다 (일부 설정의 일부 플랫폼에서는 Visual C++의 구조화 된 예외처럼 다른 예외도 catch합니다).

어떤 예외가 발생했는지 전혀 알 수없는 경우 시스템의 상태를 알 수 없습니다. 프로그램을 계속 실행하는 것이 안전한지 어떻게 알 수 있습니까?

catch(...) 블록을 종료하는 것이 절대적으로 안전한 두 가지 방법은 프로그램을 종료하거나 예외를 다시 제기하는 것입니다 (throw; 사용). 후자는 예외가 발생했지만 소멸자에 의존 할 수없는 경우 정리를 수행해야하는 경우에 유용합니다.

+3

당신이해야 할 정리가 있다면 합리적 일 수 있습니다.'throw; 완료되면 다시 던지기. 물론 RAII 클래스를 사용하는 것이 훨씬 더 좋습니다. – bdonlan

+0

@bdonlan : 당신은 절대적으로 옳았습니다. RAII 컨테이너를 직접 쓰고있는 상황에서는'catch (...) '를 사용하는 것이 유용 할 수 있다고 생각합니다. 이게 가능 하겠지만). –

+0

스택 해제 중에 소멸자에서 발생하는 예외로 인해 프로그램이 중단됩니다. RAII 컨테이너에서 소멸자에서 예외가 발생할 때 프로그램을 명시 적으로 중단하면 스택 되감기를하지 않아도 중단이 발생하는지 확실히 알 수 있습니다. – bdonlan

1

모든 예외를 포착합니다. 이 매개 변수를 선언 할 필요가 없습니다 MSDN

에서

try { 
    throw CSomeOtherException(); 
} 
catch(...) { // Handle all exceptions 
    // Respond (perhaps only partially) to exception 
    throw;  // Pass exception to some other handler 
} 

;이 코드를 참조하십시오 대부분의 경우 예외 유형의 예외가 발생했음을 핸들러에 알리는 데 충분할 수 있습니다. 그러나 예외 선언을 에 선언하지 않으면 의 해당 개체에 액세스 할 수 없게됩니다.

피연산자가없는 throw 식은 현재 처리 예외를 다시 throw합니다. 이러한 표현식은 catch 처리기 또는 catch 처리기 내에서 호출 된 함수에서만 나타납니다. 다시 throw 된 예외 개체는 원래 예외 개체입니다 ( 복사본이 아닙니다). 예 :

희망이 있습니다.

이 방법은 예외 처리를 위해 작성된 적절한 처리기가있는 경우에만 안전합니다. 그것을 피하는 것이 내 의견으로는 더 좋다.

3

catch(...) 캐치 모두 예외.

일반적으로 원하지 않을 것입니다. 당신은 당신이 무엇을 잡았는지 전혀 몰라요. 만약 당신이 catch 블록을 떠나면, 당신은 일종의 오류를 조용히 무시했습니다. 이것은 나중에 일어나는 아주 나쁜 일들을 초래할 수 있습니다. 방금 어떤 오류가 발생했는지 알지 못하기 때문에 복구 할 수있는 방법이 없으므로 예외를 계속 수행하거나 (재실행하거나) 프로그램 실행을 중단 할 수 있습니다 (abort() 또는 exit()).말했다

try { 
    // ... 
} catch (...) { 
    abortTransaction(); 
    throw; 
} 

, 그것은 일반적으로 : 당신은 당신이 수행해야 할 몇 가지 정리가있을 경우

그러나, 예외가 정리 한 다음 다시 던져을, 모든 예외를 잡을 수행하는 것이 합리적 일 수있다

DBTransaction txn = db.StartTransaction(); 

// do stuff that may throw; if it throws, txn will be destroyed, 
// and its destructor can abort the transaction 
// As such, an explicit try { } catch(...) { } isn't needed