열렬히.뛰기

예외처리 (try-catch)

Language > 프로그래밍 언어 > C++ > Cpp : 기초 > 예외처리 (try-catch)

try-catch문

예시 코드

cpp
try { 

	// 예외 발생 상황
	if ()
		throw ...
}
catch (...) { ... }
catch (...) { ... }
cpp
void customTerminate()
{
	std::abort();
}


int main() {
		// 예외처리가 없는 경우
		std::set_terminate();	


    try {
        // 예외를 발생시킬 수 있는 코드
        int numerator = 10;
        int denominator = 0;

        if (denominator == 0) {
            // 0으로 나누는 예외를 발생시킴
            throw std::runtime_error("나누는 수가 0입니다.");
        }
        int result = numerator / denominator;
        std::cout << "나눈 결과: " << result << std::endl;
    } 
		catch (const std::exception& e) {
        // 예외가 발생했을 때 실행되는 코드
        std::cerr << "예외 발생: " << e.what() << std::endl;
    }
    return 0;
}

작동 방식

  1. try 문 내의 코드를 실행

  2. 이때 예외가 발생(throw)하지 않으면 맨 마지막 catch 절 바로 다음으로 이동한다.

  3. 만약 예외가 발생하면 catch 핸들러는 다음 순서로 적절한 catch 절을 찾는다. (= 스택 풀기)

3-1. 스택에서 try 문과 가장 가까운 catch 절부터 차례대로 검사

3-2. 적절한 catch 절을 찾지 못하면, 바로 다음 바깥쪽 try 문 다음에 위치한 catch 절을 차례대로 검사

3-3. 이 과정을 가장 바깥쪽 try 문까지 계속 반복해서 검사.

3-4. 그래도 적절한 catch 절을 찾지 못하면, 미리 정의된 set_terminate() 함수가 호출됩니다.

  1. 만약 적절한 catch 절을 찾게 되면, throw 문 뒤의 변수/객체를 catch문의 매개변수로 전달

  2. 모든 예외 처리가 끝나면 프로그램의 제어는 맨 마지막 catch 절 바로 다음으로 이동

terminate()

std::terminate() 함수는 예외가 처리되지 않고 호출 스택을 거슬러 올라가 예외 처리가 가능한 catch 블록을 찾지 못했을 때 호출되는 함수다. 자동으로

이 함수는 기본적으로 예외를 처리할 수 없는 상황에서 프로그램을 종료시키는 역할을 한다.

만약 사용자가 terminate() 함수를 임의로 만들고 싶다면 set_terminate() 함수를 적고, 파라미터로 어떤 동작을 할지 정해줄 함수의 포인터를 넣어주면 된다.

exception 클래스

무엇을 throw 할 것인가?

  • 기본 자료형을 throw 해도 된다. 그러나 어떤 예외인지를 표현하는데 있어 한계가 있다.
  • 그래서 throw 전용 객체를 만들어줬는데, 이 객체의 타입이 바로 exception (예외) 클래스 이다.

exception 클래스의 구성

cpp
1. what()이라는 멤버 함수를 제공
	- what() 자체는 가상함수
	- 따라서 자식함수에서 재정의해서 무엇을 출력할지 정의할 수 있음.
2. exception 자체를 직접 쓰지 않고, exception의 자식 클래스를 씀.
	- 대표적인 자식 클래스 : logic_error, runtime_error 등등...
	- 사용자가 직접 자식 클래스를 만들 수도 있음.

what()은 다음과 같이 생겼다.

cpp
// 예전 방식 (C++98, C++03)
virtual const char *what() const throw();

// 최신 방식 (C++11 이후)
virtual const char *what() const noexcept;

// 맨 뒤 throw()나 noexcept는 이 함수가 예외를 던지지 않음을 의미.