1. exception 클래스
- c++가 제공하는 클래스로써 여러 예외클래스의 기초클래스로 사용할 수 있음
#include <stdexcept>
헤더파일로 사용- what()이라는 가상멤버함수 제공
- 즉 예외클래스를 직접 만든다면 파생클래스의 what()이라는 함수에 원하는 문자열을 출력하도록 재정의 하면 됨
2. 표준 예외 클래스
1) logic_error
- 일반적인 논리에 대한 오류처리
2) runtime_error
- 프로그램 실행 중 발생하는 다양한 오류처리
3. 예외의 종류
예외클래스 | 언제 던져지는가 | 해당 예외의 헤더파일 |
bad_alloc | new/new[]연산자로 동적메모리 할당에 실패하는 경우 예를들어 컴퓨터에 메모리 자원이 부족한 경우 |
new |
bad_cast | dynamic_cast연산에서 캐스팅이 실패하는 경우 예를들어 부모객체를 자식클래스에 캐스팅 시도하는 경우 |
typeinfo |
bad_typeid | typeid연산자가 null포인터를 반환하는 경우 예를들어 typeid(특정nullptr변수).name()처럼 사용하는 경우 |
|
bad_exception | void func() throw (int, char) {} 처럼 작성된 함수에서 int나 char가 아닌 string예외가 발생하는 경우 |
exeption |
length_error | 최대 허용 길이를 초과하는 객체를 만들려 할 때 예를 들어 vector<int> my_vector;를 만들고 my_vector.resize(my_vector.max_size()+1); 처럼 사용하는 경우 |
stdexcept |
domain_error | 수학적인 도메인 에러를 탐지할때(결과가 존재하지 않는 인자) 예를들어 루트 안에 음수값이 들어간 경우 |
|
out_of_range | 배열 범위 검사에서 인자가 index 범위를 초과할때 예를들어 string str = "abc";를 만들고 str.at(10);처럼 사용 시 at멤버가 던짐 |
|
invalid_argument | 함수 인자의 값이 유효하지 않을때 예를 들어 char 자료형은 0~255를 보관할 수 있는데 여기에 256을 넣으려고 할때 |
|
overflow_error | 산술 계산에서 상한값을 초과할 때 예를 들어 아주아주 작은 값으로 나눌 때 |
|
underflow_error | 산술 계산에서 하한값을 초과할 때 예를들어 아주아주 큰 값으로 나눌 때 |
|
range_error | 계산에서 부동 소수점 값이 너무 크거나 작아서 표현할 수 없을 때 표준 라이브러리의 수학함수들은 이 예외를 발생시키지 않음 |
|
bad_function_call | 함수 포인터를 이용해 함수를 호출했는데 해당 포인터값이 nullptr인 경우 |
|
bad_weak_ptr | 만료된 weak_ptr로 생성된 경우 shared_ptr의 생성자에 의해 예외 발생 예를들어 shared_ptr<int> sp(new int(10)); 처럼 만든 후 weak_ptr<int> wp(sp);처럼 weak_ptr을 만들고 p.reset();함수를 사용하면 weak_ptr은 소멸되는데 이 후 wp변수를 사용하는 경우 예외 발생 |
4. 함수에 붙은 throw()
다른 프로그래머가 해당 함수가 어떤 예외를 던지는지 확인하기 쉽게 throw를 이용해 작성해둘 수 있음
함수형태 | 설명 |
void func() {} | 일반적으로 사용해왔던 함수 형태해당 함수는 어떤 예외던 던질수 있으며 또는 예외를 던지지 않을수도 있음 |
void func() throw(char*, int) {} | 해당 함수는 char*형식과 int형식의 예외를 던진다는것을 알 수 있음만약 char*이나 int가 아닌 다른 예외를 던지면 bad_exception예외가 발생 |
void func() throw() void func() noexcept |
해당 함수는 예외를 던지지 않는다는 것을 의미 |
5. bad_exception 예외 처리법
bad_exception이 발생하는 경우 지정하지 않은 예외가 발생했으므로 프로그램이 강제로 종료되는데
이를 막기 위해 unexpected 또는 terminate를 사용해서 bad_exeption 예외를 처리해 줄 수 있음
#include <iostream>
#include <exception>
void my_unexpected() {
std::cerr << "unexpected handler called\n";
throw; // bad_exception이 이 핸들러(함수)로 넘어온 상황인데 이걸 또 throw;해주면 또 상위함수로 던져질테니 아래의 메인함수로 던져짐
}
void func() throw (int) {
throw 'x'; // 예외로 던져진다고 작성된 int가 아닌 char객체가 예외로 던져짐
// 즉 bad_exception 발생
}
void main() {
std::set_unexpected(my_unexpected); // 또는 std::set_terminate(my_unexpected);
// bad_exception이 발생할 경우 my_unexpected 핸들러가 처리하도록 등록해두는 것
try {
func();
}
catch (int) { std::cerr << "int 예외 발생\n; }
catch (std::bad_exception& be) { std::cerr << "bad_exepcion 예외 발생\n; }
}
위 코드를 실행하게 되면 실행결과로 아래처럼 2줄이 출력됨
unexpected handler called
bad_exepcion 예외 발생
근데 그냥 try - catch문에서 처리하면 되는거 아닌가... 따로 만들어서 처리해야 할 상황이 있나봄