학습
C++ 기본적인 예외 처리
C++ 기본적인 예외 처리 — 초급
C++ 기본적인 예외 처리
1. 도입 (왜 배워야 하는가)
C++에서 예외 처리는 프로그램의 안정성과 신뢰성을 높이는 중요한 기술입니다. 실무에서 복잡한 시스템을 개발할 때, 예외 처리 없이 코드를 작성한다면 예상치 못한 오류로 인해 프로그램이 비정상적으로 종료될 수 있습니다. 예를 들어, 파일을 열 때 해당 파일이 존재하지 않거나, 사용자 입력 값이 잘못된 경우가 있을 수 있습니다. 이러한 상황에서 적절한 예외 처리를 하지 않으면 프로그램의 사용자는 불편을 겪고, 개발자는 수많은 디버깅 작업을 해야 합니다. 따라서 예외 처리를 통해 오류 발생 시 적절한 대처를 할 수 있도록 만드는 것이 필수적입니다.
2. 핵심 개념 설명
예외 처리란 프로그램 실행 중 발생할 수 있는 오류를 관리하는 방법입니다. C++에서는 try, catch, throw 키워드를 사용하여 예외를 처리합니다.
- try: 예외가 발생할 가능성이 있는 코드 블록을 정의합니다.
- catch: 특정 예외가 발생했을 때 실행될 코드를 정의합니다.
- throw: 예외를 발생시키는 데 사용됩니다.
실생활 비유
예를 들어, 당신이 음식을 주문하는 상황을 생각해봅시다. 만약 레스토랑에서 음식을 주문했는데 재료가 떨어졌다면, 직원이 "죄송하지만 이 메뉴는 더 이상 제공되지 않습니다"라고 말하는 것이 catch에 해당합니다. 이때 직원은 고객에게 다른 메뉴를 추천하거나, 다음에 주문할 수 있도록 안내할 수 있습니다. 이처럼 예외 처리는 시스템이 예외적인 상황을 만났을 때 어떻게 반응해야 할지를 정의합니다.
관련 용어 정리
| 용어 | 설명 |
|---|---|
| 예외 | 프로그램 실행 중 발생할 수 있는 오류 상황 |
| 예외 처리 | 예외 발생 시 어떻게 대처할 것인지 정의하는 것 |
| 예외 객체 | 발생한 예외에 대한 정보를 담고 있는 객체 |
3. 기본 코드 예제
아래는 기본적인 예외 처리 방법을 보여주는 코드입니다.
#include <iostream>
#include <stdexcept> // 예외 처리 관련 헤더
int divide(int a, int b) {
if (b == 0) {
throw std::invalid_argument("0으로 나눌 수 없습니다."); // 예외 발생
}
return a / b; // 나누기 연산
}
int main() {
try {
std::cout << divide(10, 2) << std::endl; // 정상적인 나누기
std::cout << divide(10, 0) << std::endl; // 예외 발생
} catch (const std::invalid_argument& e) {
std::cerr << "오류: " << e.what() << std::endl; // 예외 처리
}
return 0;
}
실행 결과
5
오류: 0으로 나눌 수 없습니다.
코드 한 줄씩 동작 설명
#include <iostream>: 입출력 스트림을 사용하기 위한 헤더 파일을 포함합니다.#include <stdexcept>: 표준 예외 클래스를 사용하기 위한 헤더 파일을 포함합니다.int divide(int a, int b): 두 정수를 나누는 함수를 정의합니다.if (b == 0): 분모가 0인지 확인합니다.throw std::invalid_argument("0으로 나눌 수 없습니다.");: 분모가 0일 경우 예외를 발생시킵니다.return a / b;: 정상적인 경우 나눈 값을 반환합니다.int main(): 프로그램의 시작점인 메인 함수를 정의합니다.try { ... }: 예외가 발생할 수 있는 코드 블록을 감싸서 처리합니다.std::cout << divide(10, 2) << std::endl;: 정상적으로 나누기를 수행하고 결과를 출력합니다.std::cout << divide(10, 0) << std::endl;: 예외를 발생시키는 나누기를 수행하려고 합니다.catch (const std::invalid_argument& e): 발생한 예외를 처리하는 블록입니다.std::cerr << "오류: " << e.what() << std::endl;: 예외 메시지를 출력합니다.- 예외 처리는 프로그램의 안정성과 신뢰성을 높이는 중요한 기술입니다.
try,catch,throw를 사용하여 예외를 처리합니다.- 예외 발생 시 적절한 대처를 통해 사용자에게 친숙한 경험을 제공합니다.
- 다음에는 C++의 사용자 정의 예외 처리나, 예외 안전성을 높이기 위한 RAII 패턴을 학습하는 것을 추천합니다.
4. 실전 활용 예제
예제 1: 파일 열기
쇼핑몰 시스템에서 사용자가 요청한 상품 정보를 파일에서 읽어올 때, 파일이 존재하지 않거나 읽기 권한이 없을 경우 예외 처리를 통해 안정성을 높일 수 있습니다.
#include <iostream>
#include <fstream>
#include <stdexcept>
void readFile(const std::string& filename) {
std::ifstream file(filename);
if (!file.is_open()) {
throw std::runtime_error("파일을 열 수 없습니다."); // 예외 발생
}
// 파일 읽기 로직...
}
int main() {
try {
readFile("nonexistent.txt"); // 존재하지 않는 파일
} catch (const std::runtime_error& e) {
std::cerr << "오류: " << e.what() << std::endl; // 예외 처리
}
return 0;
}
예제 2: 사용자 입력 검증
사용자로부터 나이 정보를 입력받을 때, 음수나 비정상적인 값이 입력되면 예외를 발생시켜 처리합니다.
#include <iostream>
#include <stdexcept>
void setAge(int age) {
if (age < 0) {
throw std::invalid_argument("나이는 음수가 될 수 없습니다."); // 예외 발생
}
std::cout << "나이: " << age << std::endl;
}
int main() {
try {
setAge(-5); // 잘못된 나이 입력
} catch (const std::invalid_argument& e) {
std::cerr << "오류: " << e.what() << std::endl; // 예외 처리
}
return 0;
}
5. 흔한 실수와 주의사항
실수 1: 예외를 무시하기
예외를 발생시키고 catch 블록에서 아무런 처리도 하지 않는 경우.
try {
throw std::runtime_error("예외 발생");
} catch (...) {
// 아무 처리도 하지 않음
}
-> 올바른 코드: 예외를 무시하지 말고 적절한 메시지나 대체 행동을 정의해야 합니다.
실수 2: 잘못된 예외 타입
예외를 처리할 때 잘못된 타입을 사용하는 경우.
try {
throw std::invalid_argument("잘못된 인자");
} catch (const std::runtime_error& e) { // 잘못된 타입
std::cerr << e.what() << std::endl;
}
-> 올바른 코드: 예외 타입에 맞는 catch 블록을 사용해야 합니다.