Exception 클래스
예외 클래스
C++은 여러 예외를 처리하기 위해 exception 헤더 파일을 통한 다양한 예외 클래스를 제공하고 있습니다.
이러한 예외 클래스는 오류 코드값을 가지는 멤버 변수 및 오류 코드를 검사하거나 오류 메시지를 출력하는 멤버 함수 등 오류에 대한 모든 처리가 가능하도록 다양한 멤버를 포함하고 있습니다.
이와 같은 예외 클래스도 클래스이므로, 상속할 수도 있으며 다형성도 성립합니다.
또한, C++에서는 생성자와 연산자에서도 예외 처리 기능을 사용할 수 있습니다.
exception 클래스
C++은 여러 예외 클래스의 기초 클래스로 사용할 수 있는 exception 클래스를 제공합니다.
exception 클래스는 시스템에 따라 하나의 문자열 포인터를 반환하는 what()이라는 가상 멤버 함수를 제공합니다.
이 멤버 함수는 가상 함수이므로, exception 클래스로부터 파생된 클래스 내에서 재정의할 수 있습니다.
exception 클래스의 what() 멤버 함수는 별다른 일을 하지는 않지만, 파생 클래스에서는 원하는 문자열을 출력할 수 있도록 재정의할 수 있습니다.
표준 예외 클래스
표준 C++ 라이브러리는 exception 클래스로부터 파생된 다양한 표준 예외 클래스를 정의하고 있습니다.
이러한 표준 예외 클래스는 stdexcept 헤더 파일을 통해 제공되며, 논리 오류와 런타임 오류로 나눌 수 있습니다.
stdexcept 헤더 파일은 우선 다른 표준 예외 클래스의 기초 클래스가 되는 두 개의 클래스를 정의합니다.
1. logic_error
2. runtime_error
logic_error 클래스는 일반적인 논리에 관한 오류들을 처리할 수 있습니다.
runtime_error 클래스는 프로그램이 실행하는 동안 발생할 수 있는 다양한 오류들을 처리할 수 있습니다.
처리되지 않은 예외
C++ 프로그램은 발생한 예외를 처리할 catch 절을 찾을 수 없을 때, 미리 정의된 terminate() 함수를 호출합니다.
이 terminate() 함수는 기본적으로 abort() 함수를 호출하여 프로그램을 강제로 종료시킵니다.
하지만 set_terminate() 함수를 사용하면 이러한 terminate() 함수의 기본 동작을 변경할 수 있습니다.
다음 예제는 set_terminate() 함수를 이용해 처리되지 않은 예외를 위한 함수를 재정의하는 예제입니다.
예제
#include <iostream>
#include <exception>
using namespace std;
void MyErrorHandler()
{
cout << "처리되지 않은 예외가 발생했습니다." << endl;
exit(-1);
}
int main(void)
{
set_terminate(MyErrorHandler);
try { throw 1; }
catch (char* const ex) { // 이 catch 절은 정수형 예외를 처리할 수 없음. }
return 0;
}
실행 결과
Exception
위의 예제의 try 문에서는 정수형 예외가 발생했지만, 아래의 catch 절은 해당 예외를 처리하지 못합니다.
따라서 발생한 예외는 처리되지 않으며, 따라서 set_terminate() 함수로 미리 정의한 내용이 출력되게 됩니다.
예외 처리 시 주의 사항
예외가 발생하여 실행되고 있던 프로그램이 중지되는 현상은 매우 심각한 상황입니다.
따라서 발생한 예외를 처리하는 노력은 매우 중요합니다.
하지만 이러한 예외 처리에는 개발자의 많은 노력이 필요하게 됩니다.
또한, C++의 예외 처리 기능을 사용하면 프로그램의 크기가 커지고 실행 속도가 크게 떨어지는 단점이 있습니다.
따라서 무조건 발생할 수 있는 모든 예외를 다 처리하는 것이 아니라, 적당한 타협점을 찾는 게 중요합니다.