차이점 : std :: runtime_error vs std :: exception ()


127

차이점은 무엇이며 std::runtime_error그리고 std::exception? 각각에 적합한 사용법은 무엇입니까? 처음에는 왜 다른가요?

답변:


152

std::exception예외 계층에서 기본 클래스 역할을하는 것이 유일한 목적인 클래스입니다. 다른 용도는 없습니다. 즉, 개념적으로 그것은이다 추상 (이 용어의 의미 C에서 추상 클래스 ++로 정의되지 않은 경우에도) 클래스.

std::runtime_errorstd::exception다양한 런타임 오류 가 발생했을 때 발생하도록 보다 전문화 된 클래스 입니다. 두 가지 목적이 있습니다. 그것은 그 자체에 의해 발생 될 수있다, 또는 같은 런타임 오류 예외의 다양한 훨씬 더 전문 유형에 대한 기본 클래스 역할을 할 수 있습니다 std::range_error, std::overflow_error등 당신은 당신의 자신의 예외 클래스에서 내림차순으로 정의 할 수 있습니다 std::runtime_error뿐만 아니라, 당신이 당신의 자신의 예외를 정의 할 수 있습니다 에서 내림차순 클래스 std::exception.

마찬가지로 std::runtime_error표준 라이브러리에는을 포함 std::logic_error하여을 포함 std::exception합니다.

이 계층 구조의 핵심은 사용자에게 C ++ 예외 처리 메커니즘의 모든 기능을 사용할 수있는 기회를 제공하는 것입니다. 'catch'절은 다형성 예외를 포착 할 수 있으므로 사용자는 예외 계층 구조의 특정 하위 트리에서 예외 유형을 포착 할 수있는 'catch'절을 작성할 수 있습니다. 예를 들어, 하위 트리 catch (std::runtime_error& e)에서 모든 예외를 포착 std::runtime_error하여 다른 모든 트리를 통과 (및 호출 스택 위로 추가) 할 수 있습니다.

PS 유용한 예외 클래스 계층을 설계하는 것은 (코드의 각 지점에서 관심있는 예외 유형 만 잡을 수 있도록하는) 사소한 작업이 아닙니다. 표준 C ++ 라이브러리에서 볼 수있는 것은 언어 작성자가 제공하는 한 가지 가능한 방법입니다. 보시다시피 모든 예외 유형을 "런타임 오류"와 "논리 오류"로 나누고 자체 예외 유형으로 진행할 수 있도록 결정했습니다. 물론 해당 계층 구조를 구성하는 다른 방법이 있으므로 설계에 더 적합 할 수 있습니다.

업데이트 : 이식성 Linux와 Windows

Loki Astari와 unixman83이 아래 답변과 의견에서 언급했듯이 exception클래스 생성자는 C ++ 표준에 따라 인수를 사용하지 않습니다. Microsoft C ++에는 exception클래스 에서 인수를 취하는 생성자가 있지만 이는 표준이 아닙니다. 이 runtime_error클래스에는 char*Windows 및 Linux 플랫폼 모두에서 인수 ( )를 취하는 생성자가 있습니다. 휴대하기 쉽도록 사용하십시오 runtime_error.

(그리고 프로젝트 사양에 따라 코드를 Linux에서 실행할 필요가 없다고해서 Linux에서 실행할 필요는 없습니다.)


1
감사합니다. 좋은 대답입니다. 비록 다른 유형의 예외를 가질 필요가 있는지 궁금합니다 ... 단지 생각하십시오.
sivabudh

1
예외를 다시 발견 할 수있는 가능성이있는 경우 예외 처리 메커니즘을 사용하여 예외를 처리기로 처리하여 문제를 해결하려는 다른 유형의 예외가 유용 할 수 있습니다. 표준 예외 중 하나보다 복구 가능성이 없으면 괜찮습니다.
Martin York

1
제쳐두고 : 어디서나 당신을 파생시키는 규칙은 없습니다 std::exception. 물론 모든 std것은 파생 클래스를 던지지 만 std::exception파생 객체 만 던질 이유는 없습니다 .
rubenvb

1
@rubenvb 나는 그것에 대해 몰랐지만 예외에서 파생 된 클래스의 객체 만 던져지면 향후 유지 보수를 위해 코드를 정리 할 것이라고 생각합니다. 예 : 코드 기반으로 구현 된 사용자 지정 예외를 찾고 예외에서 파생 된 클래스를 검색하고 싶습니다.
this.myself

21

std::exception표준 예외 계층의 추상 기반을 고려해야합니다. 특정 메시지를 전달할 메커니즘이 없기 때문입니다 (이를 수행하려면 파생하고 전문화해야 함 what()). std :: exception을 사용하는 것을 막을 수있는 것은 없으며 간단한 응용 프로그램의 경우 필요한 모든 것입니다.

std::runtime_error반면에 문자열을 메시지로 받아들이는 유효한 생성자가 있습니다. 때 what()호출되는 const를 문자 포인터가 반환되는 생성자에 전달 된 것과 동일한 문자열이있는 C 문자열에서 포인트.

try
{
    if (badThingHappened)
    {
         throw std::runtime_error("Something Bad happened here");
    }
}
catch(std::exception const& e)
{
    std::cout << "Exception: " << e.what() << "\n";
} 

1
답변 마틴에 감사드립니다. 그러나 위에서 설명한 것과 같은 방법으로 std :: exception ()을 사용합니다. 즉 std :: exception () 생성자는 std :: string () 또는 const char *를 사용할 수도 있습니다.
sivabudh

14
표준에 따르지 않습니다. std :: exception에는 인수를 사용하지 않는 생성자가 하나 있습니다. std :: string 또는 C-String을 허용하는 버전을 사용하는 것은 이식성이 없습니다.
Martin York

10
마이크로 소프트 때문에 나는 던지기에 익숙해졌다 std::exception(std::string). 이제 std::runtime_error코드를 Linux (GCC)에서 작동 시키려면 던져야한다는 것을 알게 되었습니다.
unixman83
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.