예외는 데이터베이스 연결이 끊어지거나 예상하지 못한 입력을 만나는 등 정상적인 프로그램 기능에서 벗어난, 실행 중 발생하는 이상 현상
일반적으로 예외 처리는 프로그램 한 부분에서 자체적으로 해결할 수 없는 문제를 감지하고, 그 문제가 감지부에서 계속해서 프로그램을 실행할 수 없는 것일 때 사용
C++에서 예외 처리는 다음을 포함: throw 표현식, try 구역, exception 클래스
1. Throw 표현식
감지부에서 처리할 수 없는 무언가를 만났음을 나타내는 데 사용. 이 때 throw에서 예외를 일으킨다고 함.
int num1=0;
cout << "Enter a number (100 or less integer) :";
cin >> num1;
if (num1 > 100)
throw runtime_error("You must enter 100 or less integer.");
cout << num1 << endl;
100을 초과하는 입력을 넣으면 런타임 오류가 나는 것을 확인할 수 있음
위 코드에서는 100을 초과하는 입력을 받으면 runtime_error 타입 객체인 표현식을 던짐.
예외를 발생시키면 현재 함수를 마치고 이 오류를 처리할 수 있는 처리자로 제어를 옮김.
2. Try 구역
처리부에서 예외를 처리하는 데 사용.
try 구역은 try 키워드로 시작하고 하나 이상인 catch 절로 마침.
try 구역 안에서 실행한 코드에서 발생한 예외는 일반적으로 여러 catch 절 중 하나에서 처리.
try 구역의 일반적인 형식은 다음과 같음
try{
(logic 1)
}catch (exception-declaration) {
(logic 2)
} …
try 구역은 try 키워드로 시작.
try 구역 다음에는 하나 이상인 catch 절 목록이 옴.
catch는 catch 키워드, 괄호 안에 있는 객체의 선언, 구역 이 세 가지로 구성.
int num1=0;
while (1) {
try {
cout << "Enter a number (100 or less integer) :";
cin >> num1;
if (num1 > 100)
throw runtime_error("You must enter 100 or less integer.");
cout << num1 << endl;
break;
}
catch (runtime_error err) {
cout << err.what() << endl;
cout << "If you wanna try again, enter y:";
char opt;
cin >> opt;
if (opt != 'y')
break;
}
}
return 0;
throw에서 설명한 바와 같이, throw가 선언되는 순간 그 에러를 처리할 처리자로 이동하여 코드를 실행함. 이는 위 예제 코드를 실행하는 것으로 알 수 있음.
여기서 중요한 것은 처리자를 찾는 동안 실행중이었던 함수를 빠져나간다는 것임.
처리자 검색은 연속적인 함수 호출과 반대임. 예외가 발생하면 그 예외를 발생한 함수를 가장 먼저 확인하고, 그 함수에서 적당한 처리자가 없으면 그 함수를 호출했던 함수를 찾아감. 이 과정을 적당한 처리자가 나올 때까지 반복함.
적합한 처리자를 찾지 못하면 terminate 라이브러리 함수로 실행을 옮기는데, 이 함수는 시스템에 따라 다르지만 프로그램을 더 이상 실행하지 않고 중단함을 보장함.
try 구역이 없으면 처리자도 있을 수 없으므로, try 구역이 없는 프로그램에서는 예외가 발생하면 terminate를 호출해 프로그램을 종료.
예외는 프로그램의 정상적인 흐름을 가로챔. 예외가 발생한 지점에서 보면 호출한 쪽에서 요청한 계산 중 일부만 처리하고 나머지는 처리하지 않은 채 남아 있을 수 있음. 일반적으로 프로그램에서 어떤 부분을 우회하게 되면 객체가 유효하지 않거나 불완전한 상태로 남아있으며, 또는 자원이 해제되지 않는 등의 일이 생길 수 있음. 예외를 처리하는 동안 적절히 정리하는 프로그램을 ‘예외에 안전하다’고 함. 예외에 안전한 코드를 만드는 것은 굉장히 어려운 일임.
프로그램에서 예외를 처리하고 계속해서 진행하려면 일반적으로 예외가 발생할 수 있는지, 객체 유효성을 보장하고 자원이 누출되지 않으며, 적절한 상태로 프로그램을 되돌리기 위해 반드시 해야 하는 것이 무엇인지 항상 알아야 함.
3. 표준 예외 및 Exception 클래스
C++ 라이브러리에서는 표준 라이브러리 함수에서 문제가 생겼을 때 이를 보고하는데 사용하는 여러 클래스를 정의.
이 클래스는 다음 네 가지 헤더에서 정의함.
exception: 가장 일반적인 예외 클래스인 exception을 정의. 이는 예외가 발생했다는 것만 알리고 다른 추가 정보는 알리지 않음.
stdexcept: 몇 가지 일반적인 목적의 예외 클래스를 정의함.
new: bad_alloc 예외 타입을 정의함. 자세히는 추후 설명
type_info: bad_cast 예외 타입을 정의. 이 또한 자세히는 추후 설명
Exception 클래스는 발생한 것에 대한 정보를 throw와 연관된 catch 사이에 전달하는 데 사용.
exception, bad_alloc, bad_cast 객체에는 기본 초기화만 할 수 있으며 이 예외 타입 객체에 초기 값을 지정할 수 있음.
다른 예외 타입은 이와 반대로 string이나 C 형식 문자열로 초기화 할 수 있으나 기본 초기화가 불가능. 그러므로 반드시 초기 값을 지정해야 하며, 이 초기 값은 발생한 오류에 대한 추가 정보를 제공하는 데 사용
stdexcept에서 정의하는 표준 예외 클래스
- exception: 가장 일반적인 유형의 문제
- runtime_error: 실행 중에만 발견할 수 있는 문제
- range_error: 실행 중 오류 – 의미 있는 값 범위를 벗어나 생성된 결과
- overflow_error: 실행 중 오류 – 오버플로한 계산
- underflow_error: 실행 중 오류 – 언더플로한 계산
- logic_error: 프로그램의 논리적 오류
- domain_error: 논리 오류 – 결과가 존재하지 않는 인자 (ex. 루트 안에 음수 값이 들어간 경우)
- invalid_argument: 논리 오류 – 적절하지 않은 인자
- length_error: 논리 오류 – 해당 타입의 최대 크기보다 더 큰 객체를 생성하려 함
- out_of_range: 논리 오류 – 유효한 범위를 넘어선 값 사용
'Programming > Programming' 카테고리의 다른 글
[C++] 사용자 정의 Vector 클래스 디자인 (0) | 2018.12.23 |
---|---|
[C++] 함수 및 다중 정의 (Overload) (1) | 2018.01.21 |
[C++] 문자열 & 벡터 (0) | 2018.01.13 |
[C++] 변수와 기본 타입 (0) | 2018.01.11 |
[C - SDL] IWBTKM 소개 및 Source (0) | 2017.12.28 |