C++ 초급 - 10. 예외 처리 (1 - try-catch 블록 (예외 처리의 기본 구조))

2025. 2. 22. 17:15프로그래밍 언어/C++

📌 10. 예외 처리

C++에서 예외 처리(Exception Handling)는 프로그램 실행 중 발생하는 오류를 안전하게 처리하는 방법이다.
이를 통해 예기치 않은 상황에서도 프로그램이 정상적으로 동작할 수 있도록 한다.


📌 10.1 try-catch 블록 (예외 처리의 기본 구조)

C++에서 예외 처리(Exception Handling)프로그램 실행 중 예상치 못한 오류가 발생했을 때, 이를 안전하게 처리하는 방법이다.
이를 통해 프로그램이 비정상 종료되지 않도록 하고, 적절한 복구 및 오류 메시지를 제공할 수 있다.
C++에서는 try-catch 블록을 사용하여 예외를 감지하고 처리할 수 있다.


📌 1. 예외 처리의 기본 개념 (try, catch)

🔹 (1) try-catch 블록이란?

  • try 블록: 예외가 발생할 가능성이 있는 코드를 포함하는 영역.
  • catch 블록: try 블록에서 발생한 예외를 처리하는 영역.

💡 기본 문법

try {
    // 예외가 발생할 가능성이 있는 코드
} 
catch (예외타입 변수명) {
    // 예외 처리 코드
}

💡 예제: 기본 try-catch 구조

#include <iostream>

int main() {
    try {
        std::cout << "예외 발생 전" << std::endl;
        throw 10;  // 예외 발생
        std::cout << "이 코드는 실행되지 않음" << std::endl;
    }
    catch (int e) {
        std::cout << "예외 발생! 예외 값: " << e << std::endl;
    }

    std::cout << "프로그램 정상 종료" << std::endl;
    return 0;
}

🔹 출력 결과

예외 발생 전
예외 발생! 예외 값: 10
프로그램 정상 종료

💡 설명

  • throw 10; → 예외가 발생하면 즉시 catch (int e) 블록으로 이동.
  • std::cout << "이 코드는 실행되지 않음"; → 예외 발생 후 실행되지 않음.
  • 예외가 처리되었기 때문에 프로그램이 정상 종료됨.

📌 2. 여러 개의 catch 블록을 활용한 다양한 예외 처리

🔹 (1) 예외 타입에 따라 다른 catch 블록 처리 가능

  • 예외 타입에 따라 적절한 catch 블록이 실행됨.
  • 각각의 예외를 다르게 처리할 수 있음.

💡 예제: int, double, std::string 타입 예외 처리

#include <iostream>
#include <string>

int main() {
    try {
        throw std::string("문자열 예외 발생!");  // 문자열 예외 발생
    }
    catch (int e) {
        std::cout << "정수 예외: " << e << std::endl;
    }
    catch (double e) {
        std::cout << "실수 예외: " << e << std::endl;
    }
    catch (std::string e) {
        std::cout << "문자열 예외: " << e << std::endl;
    }

    return 0;
}

🔹 출력 결과

문자열 예외: 문자열 예외 발생!

💡 설명

  • throw std::string("문자열 예외 발생!"); → catch (std::string e) 블록에서 처리됨.
  • throw된 타입과 catch에서 받는 타입이 일치해야 예외가 정상적으로 처리됨.

📌 3. 예외가 발생하지 않는 경우 catch 블록이 실행되지 않음

🔹 (1) try 블록 내에서 예외가 발생하지 않으면 catch 블록은 실행되지 않음

💡 예제: 예외가 발생하지 않는 경우

#include <iostream>

int main() {
    try {
        std::cout << "정상 실행 중..." << std::endl;
        // 예외가 발생하지 않음
    }
    catch (int e) {
        std::cout << "예외 발생! 예외 값: " << e << std::endl;
    }

    std::cout << "프로그램 정상 종료" << std::endl;
    return 0;
}

🔹 출력 결과

정상 실행 중...
프로그램 정상 종료

💡 설명

  • throw가 실행되지 않으면 catch 블록은 실행되지 않음.
  • 프로그램이 정상적으로 실행되고 종료됨.

📌 4. 예외 객체를 통한 추가 정보 제공

🔹 (1) 예외 객체를 사용하여 오류 메시지 전달 가능

  • 예외를 던질 때 객체를 사용하면 추가적인 정보 제공이 가능.

💡 예제: 사용자 정의 예외 객체 활용

#include <iostream>
#include <string>

class MyException {
private:
    std::string message;
public:
    MyException(std::string msg) : message(msg) {}
    std::string getMessage() { return message; }
};

int main() {
    try {
        throw MyException("사용자 정의 예외 발생!");  // 예외 객체 던지기
    }
    catch (MyException& e) {
        std::cout << "예외 발생: " << e.getMessage() << std::endl;
    }

    return 0;
}

🔹 출력 결과

예외 발생: 사용자 정의 예외 발생!

💡 설명

  • throw MyException("사용자 정의 예외 발생!"); → 예외 객체를 던짐.
  • catch (MyException& e) → 객체를 받아서 getMessage()를 호출하여 오류 메시지를 출력.

📌 5. catch(...)를 활용한 범용 예외 처리

🔹 (1) catch(...)를 사용하면 모든 타입의 예외를 처리 가능

  • 예외 타입을 모르는 경우 또는 모든 예외를 처리할 때 사용.
  • 가장 마지막 catch 블록에 위치해야 함.

💡 예제: catch(...)를 사용한 범용 예외 처리

#include <iostream>

int main() {
    try {
        throw 3.14;  // 실수형 예외 발생
    }
    catch (int e) {
        std::cout << "정수 예외: " << e << std::endl;
    }
    catch (...) {
        std::cout << "알 수 없는 예외 발생!" << std::endl;
    }

    return 0;
}

🔹 출력 결과

알 수 없는 예외 발생!

💡 설명

  • throw 3.14; → catch (int e)에서 처리할 수 없음.
  • catch(...) 블록이 실행되어 모든 예외를 처리.

📌 6. 정리

개념 설명
try-catch 블록 예외가 발생할 가능성이 있는 코드를 try 블록에 작성하고, catch 블록에서 예외를 처리
여러 개의 catch 블록 다양한 예외 유형에 대해 개별적으로 처리 가능
예외가 발생하지 않는 경우 catch 블록이 실행되지 않음
예외 객체 활용 예외 메시지와 추가 정보를 제공할 수 있음
catch(...)를 활용한 범용 예외 처리 특정 타입을 지정하지 않고, 모든 예외를 처리 가능