Programming/Programming2018. 1. 15. 03:32

예외는 데이터베이스 연결이 끊어지거나 예상하지 못한 입력을 만나는 등 정상적인 프로그램 기능에서 벗어난, 실행 중 발생하는 이상 현상

일반적으로 예외 처리는 프로그램 한 부분에서 자체적으로 해결할 수 없는 문제를 감지하고, 그 문제가 감지부에서 계속해서 프로그램을 실행할 수 없는 것일 때 사용

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: 논리 오류 유효한 범위를 넘어선 값 사용


Posted by BinZIP