C++ 초급 - 10. 예외 처리 (3 - 기본 예외 클래스 (std::exception, std::runtime_error))
2025. 2. 22. 17:23ㆍ프로그래밍 언어/C++
📌 10.3 기본 예외 클래스 (std::exception, std::runtime_error)
C++ 표준 라이브러리는 예외 처리를 위한 다양한 표준 예외 클래스(std::exception 계열)를 제공한다.
이를 활용하면 예외를 일관된 방식으로 처리하고, 예외 발생 원인을 보다 쉽게 분석할 수 있다.
📌 1. 표준 예외 클래스 (std::exception, std::runtime_error, std::logic_error 등)의 개념
🔹 (1) 표준 예외 클래스란?
- C++ 표준 라이브러리는 std::exception을 기반으로 다양한 예외 클래스를 제공.
- 모든 표준 예외 클래스는 std::exception을 상속받음.
- 예외 발생 시 what() 멤버 함수를 사용하여 예외 메시지를 제공.
💡 표준 예외 클래스 계층 구조
std::exception <-- C++ 모든 표준 예외 클래스의 기본 클래스
├── std::logic_error (논리적 오류, 실행 전에 감지 가능)
│ ├── std::invalid_argument (잘못된 함수 인자)
│ ├── std::domain_error (잘못된 수학적 연산)
│ ├── std::length_error (컨테이너 크기 초과)
│ ├── std::out_of_range (잘못된 인덱스 접근)
│
├── std::runtime_error (런타임 오류, 실행 중 감지)
│ ├── std::range_error (수치 범위 초과)
│ ├── std::overflow_error (산술 오버플로우)
│ ├── std::underflow_error (산술 언더플로우)
│ ├── std::system_error (시스템 관련 오류)
│
├── std::bad_alloc (메모리 할당 실패)
├── std::bad_cast (잘못된 타입 변환)
├── std::bad_typeid (잘못된 typeid 접근)
💡 예제: 표준 예외 클래스 기본 사용법
#include <iostream>
#include <stdexcept> // 표준 예외 클래스 헤더 포함
int main() {
try {
throw std::runtime_error("런타임 오류 발생!");
}
catch (const std::exception& e) {
std::cout << "예외 처리: " << e.what() << std::endl;
}
return 0;
}
🔹 출력 결과
예외 처리: 런타임 오류 발생!
💡 설명
- std::runtime_error("런타임 오류 발생!")을 throw하여 예외 발생.
- catch (const std::exception& e)에서 what()을 사용하여 오류 메시지 출력.
📌 2. what() 함수를 활용한 예외 메시지 출력
🔹 (1) std::exception::what()의 역할
- 모든 표준 예외 클래스는 what() 함수를 제공하여 예외 메시지를 문자열(const char*)로 반환.
- 예외 발생 원인을 쉽게 확인 가능.
💡 예제: what() 함수 활용
#include <iostream>
#include <stdexcept>
int main() {
try {
throw std::invalid_argument("잘못된 인자 전달!");
}
catch (const std::exception& e) {
std::cout << "예외 발생: " << e.what() << std::endl;
}
return 0;
}
🔹 출력 결과
예외 발생: 잘못된 인자 전달!
💡 설명
- std::invalid_argument를 사용하여 잘못된 함수 인자가 전달되었음을 알림.
- what() 함수를 사용하면 예외 원인을 쉽게 파악 가능.
📌 3. 사용자 정의 예외 클래스를 std::exception에서 상속하여 만들기
🔹 (1) std::exception을 상속하여 새로운 예외 클래스 생성 가능
- 사용자 정의 예외를 만들 때 std::exception을 상속받아 what()을 오버라이딩하면 예외 메시지 제공 가능.
💡 예제: 사용자 정의 예외 클래스
#include <iostream>
#include <exception>
// 사용자 정의 예외 클래스
class MyException : public std::exception {
public:
const char* what() const noexcept override {
return "사용자 정의 예외 발생!";
}
};
int main() {
try {
throw MyException();
}
catch (const std::exception& e) {
std::cout << "예외 처리: " << e.what() << std::endl;
}
return 0;
}
🔹 출력 결과
예외 처리: 사용자 정의 예외 발생!
💡 설명
- MyException 클래스는 std::exception을 상속받아 사용자 정의 예외를 생성.
- what()을 오버라이딩하여 사용자 정의 예외 메시지를 제공.
📌 4. std::bad_alloc을 활용한 메모리 할당 예외 처리
🔹 (1) std::bad_alloc 예외
- std::bad_alloc은 메모리 할당(new)이 실패했을 때 발생하는 예외.
💡 예제: 메모리 부족으로 std::bad_alloc 예외 발생
#include <iostream>
#include <new> // std::bad_alloc 포함
int main() {
try {
// 매우 큰 배열을 할당하여 메모리 부족 발생
int* largeArray = new int[100000000000];
delete[] largeArray;
}
catch (const std::bad_alloc& e) {
std::cout << "메모리 할당 실패: " << e.what() << std::endl;
}
return 0;
}
🔹 출력 결과
메모리 할당 실패: std::bad_alloc
💡 설명
- 너무 큰 메모리를 할당하려 하면 std::bad_alloc 예외가 발생.
- catch (const std::bad_alloc& e)에서 예외를 처리하고 what()으로 메시지 출력.
📌 5. 라이브러리 함수(std::stoi, std::vector::at 등)에서 발생하는 표준 예외 처리 방법
🔹 (1) std::stoi의 std::invalid_argument 예외
💡 예제: 잘못된 문자열을 정수로 변환할 때 예외 발생
#include <iostream>
#include <string>
int main() {
try {
int num = std::stoi("abc"); // 잘못된 문자열
}
catch (const std::invalid_argument& e) {
std::cout << "예외 발생: " << e.what() << std::endl;
}
return 0;
}
🔹 출력 결과
예외 발생: stoi
💡 설명
- "abc"는 정수로 변환할 수 없으므로 std::invalid_argument 예외가 발생.
🔹 (2) std::vector::at의 std::out_of_range 예외
💡 예제: 벡터의 범위를 벗어난 인덱스 접근 시 예외 발생
#include <iostream>
#include <vector>
int main() {
try {
std::vector<int> vec = {1, 2, 3};
std::cout << vec.at(10) << std::endl; // 존재하지 않는 인덱스 접근
}
catch (const std::out_of_range& e) {
std::cout << "예외 발생: " << e.what() << std::endl;
}
return 0;
}
🔹 출력 결과
예외 발생: vector::_M_range_check: __n (which is 10) >= this->size() (which is 3)
💡 설명
- vec.at(10)을 호출하면 벡터 크기보다 큰 인덱스 접근으로 std::out_of_range 예외 발생.
📌 6. 정리
개념 | 설명 |
표준 예외 클래스 | std::exception을 기반으로 다양한 예외 클래스 제공 |
what() 함수 | 예외 메시지를 반환하여 오류 원인 분석 가능 |
사용자 정의 예외 | std::exception을 상속하여 커스텀 예외 클래스 생성 가능 |
std::bad_alloc 예외 | 메모리 할당 실패 시 발생 |
라이브러리 예외 처리 | std::stoi, std::vector::at 등의 표준 예외 활용 가능 |
'프로그래밍 언어 > C++' 카테고리의 다른 글
C++ 초급 - 11. 표준 라이브러리(STL) (2 - std::map, std::unordered_map (연관 컨테이너)) (0) | 2025.02.22 |
---|---|
C++ 초급 - 11. 표준 라이브러리(STL) (1 - std::vector, std::array (동적 및 정적 배열)) (0) | 2025.02.22 |
C++ 초급 - 10. 예외 처리 (2 - throw 키워드 (예외 발생시키기)) (0) | 2025.02.22 |
C++ 초급 - 10. 예외 처리 (1 - try-catch 블록 (예외 처리의 기본 구조)) (0) | 2025.02.22 |
C++ 초급 - 9. 템플릿 기초 (3 - C++17의 template<typename T> auto) (0) | 2025.02.22 |