학습
C++ 예외 처리 심화
C++ 예외 처리 심화 — 중급
예외 처리 심화
1. 도입 (왜 배워야 하는가)
예외 처리는 프로그램이 예상치 못한 상황에 직면했을 때 안정적으로 동작할 수 있도록 돕는 중요한 기술입니다. 실무에서는 다양한 예외 상황이 발생할 수 있으며, 이를 적절히 처리하지 않으면 프로그램이 비정상 종료되거나 데이터 손실이 발생할 수 있습니다. 예를 들어, 사용자가 입력한 데이터가 유효하지 않거나, 파일을 찾을 수 없거나, 네트워크 연결에 문제가 생길 수 있습니다. 이러한 상황에서 예외 처리를 통해 사용자에게 명확한 피드백을 제공하고, 시스템의 안정성을 높일 수 있습니다.
예외 처리를 모른다면, 프로그램이 중단되는 상황이 발생할 수 있으며, 이는 사용자 경험을 저해하고, 신뢰를 잃게 만들 수 있습니다. 따라서 예외 처리는 개발자에게 필수적인 스킬입니다.
2. 핵심 개념 설명
예외(Exception)
예외는 프로그램 실행 중 발생할 수 있는 예기치 않은 상황을 의미합니다. 이는 오류가 발생했음을 나타내며, 프로그램의 흐름을 변경할 수 있습니다.
try-catch 블록
try 블록 안에 코드를 작성하고, catch 블록을 통해 예외를 처리합니다. 마치 우리가 안전 장치를 갖춘 기계처럼, 예외 상황을 미리 대비하는 것입니다.
throw 키워드
throw 키워드는 예외를 발생시킬 때 사용합니다. 이는 마치 "불꽃이 튀는 것을 보았을 때 경고음을 울리는 것"과 같습니다.
| 용어 | 설명 |
|---|---|
| Exception | 예기치 않은 상황을 나타내는 객체 |
| try | 예외 처리를 위한 코드 블록 |
| catch | 예외를 처리하는 코드 블록 |
| throw | 예외를 발생시키는 키워드 |
3. 기본 코드 예제
다음은 기본적인 예외 처리의 예제입니다.
#include <iostream>
#include <stdexcept> // std::runtime_error를 사용하기 위해 필요
int divide(int a, int b) {
if (b == 0) {
throw std::runtime_error("0으로 나눌 수 없습니다."); // 예외 발생
}
return a / b;
}
int main() {
try {
std::cout << divide(10, 2) << std::endl; // 정상적인 나눗셈
std::cout << divide(10, 0) << std::endl; // 0으로 나누기 시도
} catch (const std::runtime_error& e) {
std::cout << "예외 발생: " << e.what() << std::endl; // 예외 처리
}
return 0;
}
실행 결과:
5
예외 발생: 0으로 나눌 수 없습니다.
코드 한 줄씩 동작 설명:
divide함수가 두 개의 정수를 인자로 받아 나눗셈을 수행합니다.- 만약 두 번째 인자가 0이라면,
throw를 통해 예외를 발생시킵니다. main함수에서try블록 안에서divide함수를 호출합니다.- 첫 번째 나눗셈은 정상적으로 실행되어 5가 출력됩니다.
- 두 번째 나눗셈에서 예외가 발생하면,
catch블록으로 넘어가 예외 메시지를 출력합니다. - 예외 처리는 프로그램의 안정성을 높이는 중요한 기술입니다.
try,catch,throw를 이용해 예외를 처리하는 방법을 배웠습니다.- 파일 처리와 사용자 입력에서 예외 처리의 필요성을 이해했습니다.
- 흔한 실수로는
catch블록 생략과 예외 발생 없이 오류 메시지만 출력하는 것입니다. - 사용자 정의 예외 클래스 만들기
- 여러 개의
catch블록 사용하기 - 예외 안전성(예: RAII) 다루기
4. 실전 활용 예제
1. 파일 읽기 예외 처리
쇼핑몰에서 사용자 업로드 파일을 처리할 때, 파일이 존재하지 않거나 형식이 잘못된 경우를 처리합니다.
#include <iostream>
#include <fstream>
#include <stdexcept>
void readFile(const std::string& filename) {
std::ifstream file(filename);
if (!file) {
throw std::runtime_error("파일을 열 수 없습니다: " + filename); // 예외 발생
}
// 파일 처리 로직...
}
int main() {
try {
readFile("없는파일.txt");
} catch (const std::runtime_error& e) {
std::cout << "예외 발생: " << e.what() << std::endl; // 예외 처리
}
return 0;
}
2. 사용자 입력 예외 처리
사용자가 나이 입력을 받을 때, 음수의 값을 입력했을 때 적절히 예외를 처리합니다.
#include <iostream>
#include <stdexcept>
void setAge(int age) {
if (age < 0) {
throw std::invalid_argument("나이는 음수가 될 수 없습니다."); // 예외 발생
}
// 나이 설정 로직...
}
int main() {
try {
setAge(-1);
} catch (const std::invalid_argument& e) {
std::cout << "입력 오류: " << e.what() << std::endl; // 예외 처리
}
return 0;
}
5. 흔한 실수와 주의사항
1. catch 블록 생략
try {
// 코드
} // catch 블록을 작성하지 않으면 예외가 처리되지 않음
올바른 코드:
try {
// 코드
} catch (const std::exception& e) {
std::cout << e.what() << std::endl; // 예외 처리
}
2. throw 없이 예외 발생
예외를 발생시키지 않고 단순히 오류 메시지를 출력하는 경우, 프로그램의 흐름이 계속 진행됩니다.
if (b == 0) {
std::cout << "0으로 나눌 수 없습니다." << std::endl; // 예외 발생 안 함
}
올바른 코드:
if (b == 0) {
throw std::runtime_error("0으로 나눌 수 없습니다."); // 예외 발생
}
6. 정리
다음에 학습하면 좋은 주제: