2017-02-27 5 views
0

std::runtime_error을 던지고 처리하지 않으면 터미널에서 자동으로 what()의 결과를 표시하여 디버깅을 훨씬 쉽게합니다. 예 :처리되지 않은 사용자 정의 예외를 throw 한 후 어떻게 what()을 호출 할 수 있습니까?

#include <iostream> 

int main() 
{ 
    throw std::runtime_error("This is an error message.\n"); 
} 

콘솔 출력이 클래스에서 파생 된

terminate called after throwing an instance of 'std::runtime_error' 
what(): This is an error message. 

사용자 정의 예외 클래스가 같은 행동을 보여, 처음부터 만든 예외 클래스는 기본적으로 그렇게하지 않습니다.

그러나 내가 만들고자하는 예외 클래스는 std::runtime_error에서 파생되어서는 안됩니다. 디버그 목적으로는 what()이 여전히 프로그램 충돌 후 인쇄되어야합니다.하지만 어떻게해야 할지를 알 수는 없습니다. 누군가 나를 기쁘게 도와 줄 수 있습니까? 순간

, 그것은 다음과 같습니다

#include <iostream> 

struct Custom_Exception 
{ 
    std::string Msg; 

    Custom_Exception(std::string Error_Msg) noexcept 
    { 
     Msg=Error_Msg; 
    } 

    std::string what() noexcept 
    { 
     return Msg; 
    } 
}; 

int main() 
{ 
    throw Custom_Exception("This is an error message.\n"); 
} 

콘솔 출력 :

terminate called after throwing an instance of 'Custom_Exception' 

오류 메시지 없음 what(): ... 소멸자에 std::cout<<Msg;을 두는 것은 도움이되지 않습니다 .

의견을 보내주세요. 고맙습니다.

+4

"하지만 내가 만들고 싶은 예외 클래스는 std :: runtime_error에서 파생해서는 안됩니다." 왜 안돼? –

+2

메인에서 예외 상황을 파악하고 원하는 조치를 취하십시오. 나는 이것을 위해 런타임에 의존하지 않을 것이다. –

+0

@NeilButterworth 특정 데이터 형식을 사용할 때마다 또는 변환 할 때마다 강제로 내 자신의 프로젝트에 사용할 일반 예외 클래스를 만들지 못하게합니다.이 기능을 추가하는 방법을 알고 싶습니다. 호기심. 나는 그런 식으로 좋아하지 않는다. 그렇지 않으면 난 그냥 std :: runtime_error 자체를 사용할 수 있습니다 ...하지만 그것은 특정 물건 std :: runtime_error 수 없기 때문에 사용자 지정 예외 클래스에 의해 싶습니다. – Thynome

답변

4

std::terminate_handlerwhat()을 사용하는 최소 예외 인터페이스는 std::exception입니다 :

struct Custom_Exception : public std::exception { 
    std::string Msg; 
public: 
    Custom_Exception(std::string Error_Msg) noexcept : Msg(Error_Msg) { 
    } 

    const char* what() const { return Msg.c_str(); } 
}; 

std::exception 인터페이스에서 상속하지 않고 또 다른 옵션은 main()

int main() 
{ 
    try { 
     throw Custom_Exception("This is an error message.\n"); 
    } 
    catch(const Custom_Exception& ce) { 
     std::cerr << ce.what() << std::endl; 
    } 
} 

에서 사용자 정의 예외를 포착하는 것입니다 또는 직접 작성하여 std::terminate_handler을 재정의하고 설정하십시오. ndler.

+0

'std :: terminate_handler'를 적절하게 오버라이드하는 법을 설명 할 수 있습니까? 그리고 그것을 어떻게 제 예외 클래스에 통합시킬 수 있습니까? – Thynome

+0

@Thynome'std :: terminate_handler' 오버 라이드 함수가'try {throw; } catch (const Custom_Exception & ce) {/ * ... * /}'. –

+0

하실 수 있습니다. [except.handle]/7에 따르면 throw *로 인해 std :: terminate() [...]가 입력되면 암시 적 핸들러 이 활성화 된 것으로 간주되므로 안전하게 예외를 다시 throw 할 수 있습니다. –

0

가상 소멸자와 가상 what() 메소드를 제공하는 std :: exception에서 예외를 파생해야합니다. 소멸자를 오버라이드하면 메시지를 인쇄 할 수 있습니다.

#include <iostream> 
#include <exception> 

class Custom_Exception : std::exception 
{ 
    char const* Msg; 

    Custom_Exception(char const* Error_Msg) noexcept 
    { 
     Msg=Error_Msg; 
    } 

    Custom_Exception(Custom_Exception const& other) 
    { 
     Msg = other.Msg; 
    } 

    Custom_Exception& operator=(Custom_Exception const& other) 
    { 
     Msg = other.Msg; 
     return *this; 
    } 

    virtual ~Custom_Exception() 
    { 
    } 

    virtual char const* what() const noexcept 
    { 
     return Msg; 
    } 
}; 

int main() 
{ 
    try 
    { 
     throw Custom_Exception("This is an error message.\n"); 
    } 
    catch (Custom_Exception& ex) 
    { 
     std::cout << "what(): " << ex.what(); 
    } 
} 
+0

예외가 발생하지 않더라도 오류 메시지가 인쇄되지 않습니까? 그리고 심지어 잡히더라도? –

+0

오, 그래. 예외가 파기 될 때마다. 그러므로 πάντα ῥεῖ의 바깥 덫에 대한 대답이 효과가있을 수 있습니다. –

+0

오류 메시지를 출력하는 것은 소멸자의 책임이 아닙니다. 이것이'what()'이 존재하는 이유이며, 필요할 때 에러 메시지를 리턴한다. –