Core Programming/Modern C++ & System Design

C++ 예외 처리 완벽 가이드: try-catch-throw 문법과 실전 예제

임베디드 친구 2024. 12. 20. 20:11
반응형

프로그램을 실행하다 보면 예기치 못한 입력값이나 리소스 부족으로 인해 프로그램이 갑자기 종료되는 경우가 있습니다. 이러한 비정상 종료를 막고 오류를 우아하게 처리하기 위해 C++은 예외 처리(Exception Handling) 기능을 제공합니다.

오늘은 C++ 예외 처리의 핵심인 try, catch, throw의 사용법부터 실무에서 주의해야 할 점까지 자세히 알아보겠습니다.

Generated by Gemini AI.


1. 예외 처리(Exception Handling)란?

예외 처리는 실행 중 발생하는 오류 상황을 감지하여, 프로그램이 죽지 않고 미리 정의된 안전한 경로로 흐르게 만드는 기법입니다.

C++ 예외 처리의 3단계

  • throw (던지기): 예외 상황이 발생했음을 알리고 예외 객체를 던집니다.
  • try (시도하기): 예외가 발생할 가능성이 있는 코드 블록을 감쌉니다.
  • catch (받기): 던져진 예외를 잡아 적절한 대책(로그 기록, 리소스 해제 등)을 수행합니다.

2. 예외 처리 기본 문법과 예제

가장 흔한 오류인 '0으로 나누기' 상황을 통해 기본 구조를 살펴보겠습니다.

C++
 
#include <iostream>
#include <string>

int main() {
    try {
        int x;
        std::cout << "나눌 숫자를 입력하세요: ";
        std::cin >> x;

        if (x == 0) {
            throw std::string("0으로 나눌 수 없습니다."); // 예외 발생!
        }

        std::cout << "결과: " << 100 / x << std::endl;
    } 
    catch (const std::string& e) { // 던진 타입과 일치하는 catch 실행
        std::cerr << "에러 발생: " << e << std::endl;
    }

    return 0;
}

3. 다중 예외 처리와 표준 예외 클래스

오류의 종류는 다양합니다. C++에서는 여러 개의 catch 블록을 두어 타입별로 대응할 수 있습니다. 또한, 직접 예외를 만들기보다 <stdexcept>에서 제공하는 표준 예외 클래스를 사용하는 것이 권장됩니다.

주요 표준 예외 클래스

  • std::runtime_error: 실행 중에 발생하는 일반적인 오류
  • std::out_of_range: 배열 인덱스 등 범위 초과
  • std::invalid_argument: 잘못된 인수가 전달된 경우
C++
 
#include <iostream>
#include <stdexcept>

void checkAge(int age) {
    if (age < 0) throw std::invalid_argument("나이는 음수일 수 없습니다.");
    if (age > 150) throw std::runtime_error("현실적이지 않은 나이입니다.");
}

int main() {
    try {
        checkAge(-5);
    } 
    catch (const std::invalid_argument& e) {
        std::cerr << "인수 오류: " << e.what() << std::endl;
    } 
    catch (const std::exception& e) { // 모든 표준 예외의 부모 클래스
        std::cerr << "기타 예외: " << e.what() << std::endl;
    }
    return 0;
}

4. 사용자 정의 예외 클래스 만들기

프로젝트의 성격에 맞춰 직접 예외 클래스를 정의할 수 있습니다. 이때 std::exception을 상속받아 what() 메서드를 오버라이딩하면 표준 예외와 일관성 있게 사용할 수 있습니다.

C++
 
class NetworkException : public std::exception {
public:
    const char* what() const noexcept override {
        return "네트워크 연결에 실패했습니다.";
    }
};

5. 예외 처리 시 반드시 주의할 점 (실무 팁)

수익형 블로그이자 전문 블로그로서 신뢰도를 높여주는 핵심 섹션입니다.

  1. catch 순서에 주의하세요: 자식 클래스 예외를 부모 클래스(std::exception)보다 먼저 배치해야 합니다. 부모 클래스가 위에 있으면 모든 예외를 다 잡아버려 구체적인 처리가 불가능해집니다.
  2. 참조자(&)로 잡으세요: 예외 객체를 잡을 때는 const exception& e와 같이 참조를 사용하세요. 객체 복사 비용을 줄이고 다형성을 유지할 수 있습니다.
  3. 소멸자에서는 예외를 던지지 마세요: 객체가 소멸되는 도중 또 다른 예외가 발생하면 프로그램이 즉시 강제 종료됩니다.
  4. 남발은 금물: 예외 처리는 일반적인 조건문(if)보다 실행 비용이 큽니다. 정말 예상치 못한 '예외' 상황에만 사용하세요.

결론

예외 처리는 단순히 오류 메시지를 띄우는 것이 아니라, 프로그램의 안정성(Robustness)을 확보하는 과정입니다. 오늘 알아본 try-catch와 표준 예외 클래스들을 활용해 더 견고한 C++ 코드를 작성해 보세요!

궁금하신 점은 댓글로 남겨주시면 답변해 드리겠습니다.

반응형