Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 예외 처리 기본 개념 총정리: try-catch부터 사용자 정의 예외까지


C++에서 예외 처리(Exception Handling)란 프로그램 실행 중에 발생하는 런타임 오류를 처리하는 메커니즘을 말합니다. 예외(Exception)는 프로그램이 실행되는 도중에 발생(throw)되는 이벤트로, C++의 모든 표준 예외는 std::exception 클래스를 기반으로 파생됩니다. 만약 예외를 적절히 처리하지 않으면, 프로그램은 예외 메시지를 출력한 뒤 비정상적으로 종료됩니다.

C++ 표준에서는 <exception> 헤더를 통해 다양한 예외 클래스를 정의하고 있으며, 이를 프로그램 안에서 자유롭게 활용할 수 있습니다. 부모-자식 클래스로 이루어진 계층 구조는 아래와 같습니다.

C++ 예외 처리 기본 개념 총정리: try-catch부터 사용자 정의 예외까지

C++의 주요 표준 예외 클래스

예외 클래스설명
std::exception모든 표준 C++ 예외 클래스의 부모(기반) 클래스입니다.
std::bad_castdynamic_cast가 실패할 때 던져지는 예외입니다.
std::bad_exception프로그램에서 예상치 못한 예외를 처리하는 데 사용됩니다.
std::bad_allocnew 연산자가 메모리 할당에 실패했을 때 일반적으로 던져지는 예외입니다.
std::logic_error코드를 검토함으로써 사전에 감지할 수 있는 논리적 오류입니다.
std::runtime_error코드 검토만으로는 감지할 수 없고 실행 중에 발생하는 오류입니다.
std::bad_typeidtypeid 연산자가 실패할 때 던져지는 예외입니다.

예외 처리의 핵심 키워드 3가지

C++의 예외 처리에는 세 가지 핵심 키워드가 사용됩니다: try, catch, throw.

  • throw: 문제가 발생했음을 알리고 예외를 던질 때 사용합니다.
  • try: 예외가 발생할 가능성이 있는 코드를 감싸는 블록입니다.
  • catch: try 블록에서 던져진 예외를 받아 처리하는 블록입니다.

Try/Catch 블록의 동작 방식

C++에서는 try/catch 문을 사용해 예외를 처리합니다. 예외가 발생할 수 있는 코드는 try 블록 안에 작성하고, 실제로 예외가 발생하면 해당 예외는 catch 블록에서 처리됩니다.

예제 코드

#include <iostream>
using namespace std;
class Sample1 {
    public:
    Sample1()
    {
        cout << "Construct an Object of sample1" << endl;
    }
    ~Sample1()
    {
        cout << "Destruct an Object of sample1" << endl;
    }
};
class Sample2 {
    public:
    Sample2()
    {
        int i=7;
        cout << "Construct an Object of sample2" << endl;
        throw i;
    }
    ~Sample2()
    {
        cout << "Destruct an Object of sample2" << endl;
    }
};
int main() {
    try {
        Sample1 s1;
        Sample2 s2;
    } catch(int i) {
        cout << "Caught " << i << endl;
    }
}

위 예제에서 주목할 점은 Sample2 객체의 생성자에서 예외가 던져졌기 때문에 Sample2의 소멸자는 호출되지 않지만, 이미 생성이 완료된 Sample1 객체의 소멸자는 정상적으로 호출된다는 것입니다. 이처럼 C++은 스택 풀기(stack unwinding) 과정을 통해 이미 생성된 지역 객체들을 자동으로 정리해 줍니다.

실행 결과

Construct an Object of sample1
Construct an Object of sample2
Destruct an Object of sample1
Caught 7

사용자 정의 예외(User Defined Exception)

C++에서는 std::exception 클래스를 상속받고 what() 함수를 재정의(오버라이딩)하여 자신만의 예외 클래스를 정의할 수 있습니다.

예제 코드

#include <iostream>
#include <exception>
using namespace std;
struct DivideByZero : public exception {
    const char * what () const throw () {
        return "My Exception";
    }
};
int main() {
    try {
        throw DivideByZero();
    } catch(DivideByZero& e) {
        cout << "Exception caught" << endl;
        cout << e.what() << endl;
    } catch(exception& e) {
    }
}

실행 결과

Exception caught
My Exception

what() 메서드란?

what()exception 클래스가 제공하는 public 메서드로, 모든 자식 예외 클래스들이 이를 재정의하여 사용합니다. 이 메서드는 예외가 발생한 원인을 설명하는 문자열을 반환하며, 어떤 문제로 인해 예외가 발생했는지 파악하는 데 유용하게 활용됩니다.