C++ 예외처리에 대해 정리한다.


예외처리(Try, Catch, Throw)

ㆍ예외 상황을 처리하는 코드부분을 독립시켜 유지보수 및 코드 가독성을 높이기 위함

기본 구성

1
2
3
4
5
6
7
try {
   / * 예외 발생 예상 지역 */
   throw ex; 	// 예외 전달(catch block으로)
}
catch (처리되어야  예외의 종류) {
   / * 예외를 처리하는 코드가 존재할 위치 */
}

전달되는 예외와 이를 받아주는 변수의 자료형은 일치해야 함

ㆍ예외의 발생 및 처리 과정

_

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
using std::cout;
using std::endl;
using std::cin;

int main(void){
    int a, b;

    cout << "두 개 숫자 입력: ";
    cin >> a >> b;

    try{
        cout << "Start a try block" << endl;

        if(b==0)
            throw b;
        cout << "a/b의 몫: "<< a/b << endl;
        cout << "a/b의 나머지: "<< a%b << endl;

        cout << "End a try block" << endl;
    }
    catch(int exception){
        cout << "Start a catch block" << endl;

        cout << exception << "입력" << endl;
        cout << "입력오류! 다시 실행하세요." << endl;

        cout << "End a catch block" << endl;
    }

    cout << "감사합니다." << endl;

    return 0;
}

ㆍ정상 실행

5

ㆍ예외 발생

6

예외가 발생하면 throw 이후의 try 블록 내의 소스들은 실행되지 않는다.

처리되지 않는 예외

Stack Unwinding(스택 풀기)

처리되지 않는 예외는 전달됨 = Stack Unwinding

예외가 전달되는 과정이 함수의 스택이 풀리는 순서와 일치하기 때문에, 이러한 명칭이 붙음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using std::cout;
using std::endl;

void fct1();
void fct2();
void fct3();

int main(void){
    try{
        fct1();
    }
    catch(int ex){
        cout << "예외: " << ex << endl;
    }
    return 0;
}

void fct1(){
    fct2();
}

void fct2(){
    fct3();
}

void fct3(){
    throw 100;
}

1

ㆍStack Unwinding 순서

_

abort 함수

처리되지 않는 예외의 경우, 헤더파일 stdlib.h 에 선언되어 있는 abort 함수가 호출됨

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using std::endl;
using std::cout;
using std::cin;

int divide(int a, int b);   // a/b 몫만 반환

int main(void){
    int a, b;

    cout << "두 개의 숫자 입력: ";
    cin >> a >> b;
    cout << "a/b의 몫: " << divide(a,b) << endl;
    return 0;
}

int divide(int a, int b){
    if(b==0)
        throw b;
    return a/b;
}

ㆍ예외 발생 시, abort() 호출될 경우 아래와 같은 오류가 발생함

22222

전달되는 예외 명시

ㆍ유지보수 수월함을 위해 일반적으로 선언

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// function1 함수는 int형 예외를 전달할 수 있다
int fucntion1(double d) throw (int)	
{
  ...
}

// function2 함수는 int형, double형, char*형 예외를 전달할 수 있다
int fucntion2(double d) throw (int, double, char *)	
{
  ...
}

// function3 함수는 어떠한 예외도 전달하지 않는다.
int fucntion3(double d) throw ()	
{
  ...
}

하나의 try + 여러 개의 catch

`