본문 바로가기

C++

[C++] 예외 객체

class Exception
{
private:
     int ErrorCode;

public:
     Exception(int ae) : ErrorCode(ae) { }
     int GetErrorCode() { return ErrorCode; }
     void ReportError() {
          switch (ErrorCode) {
          case 1:
              puts("메모리가 부족합니다.");
              break;
          case 2:
              puts("연산 범위를 초과했습니다.");
              break;
          case 3:
              puts("하드 디스크가 가득 찼습니다.");
              break;
          }
     }
}; 

void Calc()
{
     // 메모리 할당 후 연산해서 파일로 출력하는 동작을 한다고 하자.
     if (TRUE/*에러 발생*/) throw Exception(1);
     // 여기까지 왔으면 무사히 작업 완료했음
}

void main()
{
     try {
          Calc();
          puts("작업을 완료했습니다.");
     }
     catch(Exception &e) {
          printf("에러 코드 = %d => ",e.GetErrorCode());
          e.ReportError();
     }
}

 

예외 처리할 때 객체를 던질 수도 있다. 위 코드는 Exception이라는 객체를 만들어서 던지는데, 어떤 오류인지 출력하는 기능도 포함되어있다. catch문에서 객체를 예외로 받을 때는 레퍼런스형으로 받는다.

 

예외 객체간의 상속이나 가상함수 등 예외 객체도 객체이기 때문에 모두 가능하다.

 

class Position
{
private:
     int x,y;
     char ch;
     
public:
     Position(int ax, int ay, char ach)
     try : x(ax),y(ay) {
          if (ax < 0) throw ax;
          ch=ach;
     }
     catch (int a) {
          printf("%d는 음수 좌표라 객체가 보이지 않습니다.\n",a);
     }
     
     void OutPosition() {
          gotoxy(x, y);
          putch(ch);
     }
}; 

void main()
{
     try {
          Position Here(-1,10,'X');
          Here.OutPosition();
     }
     
     catch (int) {
          puts("무효한 객체임");
     }
}

 

함수 본체 코드가 try 블록 안에 모두 적혀져 있을 경우에는 함수의 {} 블록을 생략할 수 있었는데, 이는 생성자도 마찬가지이다. 위 코드에서는 생성자의 블록을 생략하고 try catch 문만 있고 try가 생성자의 초기화 리스트 앞에 있다. 그 이유는 생성자가 초기화리스트를 이용해 초기화 하는 것 까지 예외처리에 포함하기 위해서이다. 객체 생성 단계의 예외는 객체뿐만 아니라 객체를 생성한 곳도 관련이 있기 때문에 main함수에서도 try 블록을 사용해야 한다.

'C++' 카테고리의 다른 글

[C++] 캐스트 연산자 (static, dynamic, const, reinterpret)  (0) 2022.01.07
[C++] RTTI  (0) 2022.01.07
[C++] 예외 처리  (0) 2022.01.07
[C++] 클래스 템플릿  (0) 2022.01.06
[C++] 함수 템플릿  (0) 2022.01.06