프로그램을 실행하다 보면 예기치 못한 입력값이나 리소스 부족으로 인해 프로그램이 갑자기 종료되는 경우가 있습니다. 이러한 비정상 종료를 막고 오류를 우아하게 처리하기 위해 C++은 예외 처리(Exception Handling) 기능을 제공합니다.
오늘은 C++ 예외 처리의 핵심인 try, catch, throw의 사용법부터 실무에서 주의해야 할 점까지 자세히 알아보겠습니다.

1. 예외 처리(Exception Handling)란?
예외 처리는 실행 중 발생하는 오류 상황을 감지하여, 프로그램이 죽지 않고 미리 정의된 안전한 경로로 흐르게 만드는 기법입니다.
C++ 예외 처리의 3단계
- throw (던지기): 예외 상황이 발생했음을 알리고 예외 객체를 던집니다.
- try (시도하기): 예외가 발생할 가능성이 있는 코드 블록을 감쌉니다.
- catch (받기): 던져진 예외를 잡아 적절한 대책(로그 기록, 리소스 해제 등)을 수행합니다.
2. 예외 처리 기본 문법과 예제
가장 흔한 오류인 '0으로 나누기' 상황을 통해 기본 구조를 살펴보겠습니다.
#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: 잘못된 인수가 전달된 경우
#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() 메서드를 오버라이딩하면 표준 예외와 일관성 있게 사용할 수 있습니다.
class NetworkException : public std::exception {
public:
const char* what() const noexcept override {
return "네트워크 연결에 실패했습니다.";
}
};
5. 예외 처리 시 반드시 주의할 점 (실무 팁)
수익형 블로그이자 전문 블로그로서 신뢰도를 높여주는 핵심 섹션입니다.
- catch 순서에 주의하세요: 자식 클래스 예외를 부모 클래스(std::exception)보다 먼저 배치해야 합니다. 부모 클래스가 위에 있으면 모든 예외를 다 잡아버려 구체적인 처리가 불가능해집니다.
- 참조자(&)로 잡으세요: 예외 객체를 잡을 때는 const exception& e와 같이 참조를 사용하세요. 객체 복사 비용을 줄이고 다형성을 유지할 수 있습니다.
- 소멸자에서는 예외를 던지지 마세요: 객체가 소멸되는 도중 또 다른 예외가 발생하면 프로그램이 즉시 강제 종료됩니다.
- 남발은 금물: 예외 처리는 일반적인 조건문(if)보다 실행 비용이 큽니다. 정말 예상치 못한 '예외' 상황에만 사용하세요.
결론
예외 처리는 단순히 오류 메시지를 띄우는 것이 아니라, 프로그램의 안정성(Robustness)을 확보하는 과정입니다. 오늘 알아본 try-catch와 표준 예외 클래스들을 활용해 더 견고한 C++ 코드를 작성해 보세요!
궁금하신 점은 댓글로 남겨주시면 답변해 드리겠습니다.
'Core Programming > Modern C++ & System Design' 카테고리의 다른 글
| C++ 멀티스레드 프로그래밍 완벽 가이드: thread, mutex, condition_variable (0) | 2024.12.21 |
|---|---|
| C++ 파일 입출력 완벽 가이드: 바이너리 파일 읽기/쓰기 및 포인터 제어 (0) | 2024.12.21 |
| C++ STL 총정리: 컨테이너, 반복자, 알고리즘 핵심 요약 및 예제 (0) | 2024.12.20 |
| C++ 템플릿(Template) 완벽 정리: 함수·클래스 템플릿부터 특수화까지 (0) | 2024.12.20 |
| C++ 네임스페이스(Namespace) 사용법 총정리: 이름 충돌 방지와 모듈화 (0) | 2024.12.20 |