산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C++ 예외 처리 완벽 가이드: try, catch, throw 완전 정복

예외(exception)는 프로그램 실행 중에 발생하는 문제입니다. C++ 예외는 프로그램이 실행되는 동안 0으로 나누기 시도 같은 예외적 상황이 발생했을 때의 대응입니다.

예외는 프로그램의 한 부분에서 다른 부분으로 제어를 전달하는 방법을 제공합니다. C++ 예외 처리는 세 키워드 try, catch, throw를 기반으로 합니다.

블록이 예외를 발생시킬 것으로 가정하면, 메서드는 try와 catch 키워드 조합으로 예외를 잡습니다. try/catch 블록은 예외를 발생시킬 수 있는 코드 주변에 배치합니다. try/catch 블록 내 코드를 보호된 코드(protected code)라 하며, try/catch 사용 구문은 다음과 같습니다.

try {
    // 보호된 코드
} catch(ExceptionName e1) {
    // catch 블록
} catch(ExceptionName e2) {
    // catch 블록
} catch(ExceptionName eN) {
    // catch 블록
}

여러 catch 문을 나열해 try 블록이 다른 상황에서 둘 이상의 예외를 발생시킬 경우 다른 타입의 예외를 잡을 수 있습니다.

예외 던지기

예외는 throw 문을 사용해 코드 블록 어디서든 던질 수 있습니다. throw 문의 피연산자는 예외 타입을 결정하며, 어떤 표현식이든 될 수 있고 표현식 결과의 타입이 던져지는 예외 타입이 됩니다.

0으로 나누기 조건 발생 시 예외를 던지는 예제:

double division(int a, int b) {
    if(b == 0) {
        throw "Division by zero condition!";
    }
    return (a/b);
}

예외 잡기

try 블록 뒤의 catch 블록은 모든 예외를 잡습니다. catch 키워드 뒤 괄호에 나타나는 예외 선언에 의해 어떤 타입의 예외를 잡을지 결정됩니다.

try {
    // 보호된 코드
} catch(ExceptionName e) {
    // ExceptionName 예외 처리 코드
}

위 코드는 ExceptionName 타입의 예외를 잡습니다. try 블록에서 던져지는 어떤 타입의 예외든 처리하려면 예외 선언을 감싸는 괄호 사이에 줄임표 ...를 넣어야 합니다.

try {
    // 보호된 코드
} catch(...) {
    // 모든 예외 처리 코드
}

다음 예제는 0으로 나누기 예외를 던지고 catch 블록에서 잡습니다.

Live Demo
#include <iostream>
using namespace std;
double division(int a, int b) {
    if(b == 0) {
        throw "Division by zero condition!";
    }
    return (a/b);
}
int main() {
    int x = 50;
    int y = 0;
    double z = 0;
    try {
        z = division(x, y);
        cout << z << endl;
    } catch(const char* msg) {
        cerr << msg << endl;
    }
    return 0;
}

const char* 타입의 예외를 발생시키므로, 이 예외를 잡을 때 catch 블록에서 const char*를 사용해야 합니다. 컴파일하고 실행하면:

Division by zero condition!

C++ 표준 예외

C++은 <exception>에 정의된 표준 예외 목록을 제공하며, 이를 프로그램에서 사용할 수 있습니다. 이들은 부모-자식 클래스 계층으로 배열됩니다.

C++ 예외 처리 완벽 가이드: try, catch, throw 완전 정복

위 계층에 언급된 각 예외에 대한 간략한 설명:

번호예외 및 설명
1

std::exception

모든 표준 C++ 예외의 부모 클래스인 예외.

2

std::bad_alloc

new에 의해 던져질 수 있음.

3

std::bad_cast

dynamic_cast에 의해 던져질 수 있음.

4

std::bad_exception

C++ 프로그램에서 예상치 못한 예외를 처리하는 유용한 장치.

5

std::bad_typeid

typeid에 의해 던져질 수 있음.

6

std::logic_error

코드를 읽어 이론적으로 감지할 수 있는 예외.

7

std::domain_error

수학적으로 유효하지 않은 도메인이 사용될 때 던져지는 예외.

8

std::invalid_argument

잘못된 인자로 인해 던져짐.

9

std::length_error

너무 큰 std::string 생성 시 던져짐.

10

std::out_of_range

'at' 메서드에 의해 던져질 수 있음. 예: std::vector, std::bitset<>::operator[]().

11

std::runtime_error

코드를 읽어 이론적으로 감지할 수 없는 예외.

12

std::overflow_error

수학적 오버플로 발생 시 던져짐.

13

std::range_error

범위를 벗어난 값을 저장하려 할 때 발생.

14

std::underflow_error

수학적 언더플로 발생 시 던져짐.

새 예외 정의

exception 클래스 기능을 상속하고 오버라이드해 자체 예외를 정의할 수 있습니다. 다음 예제는 std::exception 클래스를 사용해 표준 방식으로 자체 예외를 구현하는 방법을 보여줍니다.

Live Demo
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception {
    const char* what() const throw() {
        return "C++ Exception";
    }
};
int main() {
    try {
        throw MyException();
    } catch(MyException& e) {
        std::cout << "MyException caught" << std::endl;
        std::cout << e.what() << std::endl;
    } catch(std::exception& e) {
        // 기타 에러
    }
}

실행 결과:

MyException caught
C++ Exception

what()은 exception 클래스가 제공하는 public 메서드이며, 모든 자식 예외 클래스에서 오버라이드되었습니다. 이는 예외의 원인을 반환합니다.

C 언어

  1. C++ 연산자 마스터하기: 유형별 완벽 가이드와 실전 예제
  2. C++ 주석: 가독성 높고 유지보수하기 좋은 코드 작성법
  3. C++ 클래스 템플릿 마스터: 실전 가이드
  4. C 파일 입출력: fopen, fprintf, fread, fseek 마스터하기
  5. Java 예외 처리 마스터: try-catch-finally, throw, throws 완전 정복
  6. C++ 예외 처리 마스터: try, catch, throw 실전 예제
  7. 파이썬 예외 처리 마스터: try, except, finally, raise 효과적 활용
  8. C 언어 에러 처리 마스터하기: 모범 사례와 기법
  9. C++ 프로그래밍 언어: 개요와 핵심 특징
  10. C++ 상수와 리터럴 완전 정복: 타입, 문법, 모범 사례