15. 예외처리(Exception Handling)
출처: 윤성우 열혈강의 C++ 예제코드
15.1. 예외상황과 예외처리의 이해
- if문을 이용한 예외처리
#include <iostream>
using namespace std;
int main(void)
{
int num1, num2;
cout<<"두 개의 숫자 입력: ";
cin>>num1>>num2;
if(num2==0)
{
cout<<"제수는 0이 될 수 없습니다."<<endl;
cout<<"프로그램을 다시 실행하세요."<<endl;
}
else
{
cout<<"나눗셈의 몫: "<< num1/num2 <<endl;
cout<<"나눗셈의 나머지: "<< num1%num2 <<endl;
}
return 0;
}
15.2. C++의 예외처리 메커니즘
- try catch를 이용한 예외처리
#include <iostream>
using namespace std;
int main(void)
{
int num1, num2;
cout<<"두 개의 숫자 입력: ";
cin>>num1>>num2;
try
{
if(num2==0)
throw num2;
cout<<"나눗셈의 몫: "<< num1/num2 <<endl;
cout<<"나눗셈의 나머지: "<< num1%num2 <<endl;
}
catch(int expn)
{
cout<<"제수는 "<<expn<<"이 될 수 없습니다."<<endl;
cout<<"프로그램을 다시 실행하세요."<<endl;
}
cout<<"end of main"<<endl;
return 0;
}
15.3. Stack Unwinding(스택 풀기)
- 예외의 전달(unwinding)
#include <iostream>
using namespace std;
void SimpleFuncOne(void);
void SimpleFuncTwo(void);
void SimpleFuncThree(void);
int main(void)
{
try
{
SimpleFuncOne();
}
catch(int expn)
{
cout<<"예외코드: "<< expn <<endl;
}
return 0;
}
void SimpleFuncOne(void)
{
cout<<"SimpleFuncOne(void)"<<endl;
SimpleFuncTwo();
}
void SimpleFuncTwo(void)
{
cout<<"SimpleFuncTwo(void)"<<endl;
SimpleFuncThree();
}
void SimpleFuncThree(void)
{
cout<<"SimpleFuncThree(void)"<<endl;
throw -1;
}
SimpleFuncOne(void)
SimpleFuncTwo(void)
SimpleFuncThree(void)
예외코드: -1
15.4. 예외상황을 표현하는 예외 클래스의 설계
- 예외 클래스와 예외객체
#include <iostream>
#include <cstring>
using namespace std;
class DepositException
{
private:
int reqDep; // 요청 입금액
public:
DepositException(int money) : reqDep(money)
{ }
void ShowExceptionReason()
{
cout<<"[예외 메시지: "<<reqDep<<"는 입금불가]"<<endl;
}
};
class WithdrawException
{
private:
int balance; // 잔고
public:
WithdrawException(int money) : balance(money)
{ }
void ShowExceptionReason()
{
cout<<"[예외 메시지: 잔액 "<<balance<<", 잔액부족]"<<endl;
}
};
class Account
{
private:
char accNum[50]; // 계좌번호
int balance; // 잔고
public:
Account(char * acc, int money) : balance(money)
{
strcpy(accNum, acc);
}
void Deposit(int money) throw (DepositException)
{
if(money<0)
{
DepositException expn(money);
throw expn;
}
balance+=money;
}
void Withdraw(int money) throw (WithdrawException)
{
if(money>balance)
throw WithdrawException(balance);
balance-=money;
}
void ShowMyMoney()
{
cout<<"잔고: "<<balance<<endl<<endl;
}
};
int main(void)
{
Account myAcc("56789-827120", 5000);
try
{
myAcc.Deposit(2000);
myAcc.Deposit(-300);
}
catch(DepositException &expn)
{
expn.ShowExceptionReason();
}
myAcc.ShowMyMoney();
try
{
myAcc.Withdraw(3500);
myAcc.Withdraw(4500);
}
catch(WithdrawException &expn)
{
expn.ShowExceptionReason();
}
myAcc.ShowMyMoney();
return 0;
}
[예외 메시지: -300는 입금불가]
잔고: 7000
[예외 메시지: 잔액 3500, 잔액부족]
잔고: 3500
15.5. 예외처리와 관련된 또 다른 특성들
- new 연산자에 의해서 발생하는 예외객체
#include <iostream>
#include <new>
using namespace std;
int main(void)
{
int num=0;
try
{
while(1)
{
num++;
cout<<num<<"번째 할당"<<endl;
new int[10000][10000];
}
}
catch(bad_alloc &bad)
{
cout<<bad.what()<<endl;
cout<<"더 이상 할당 불가!"<<endl;
}
return 0;
}
1번째 할당
2번째 할당
3번째 할당
4번째 할당
5번째 할당
bad allocation
더 이상 할당 불가!
- try catch에서 예외 던지기
#include <iostream>
using namespace std;
void Divide(int num1, int num2)
{
try
{
if(num2==0)
throw 0;
cout<<"몫: "<<num1/num2<<endl;
cout<<"나머지: "<<num1%num2<<endl;
}
catch(int expn)
{
cout<<"first catch"<<endl;
throw;
}
}
int main(void)
{
try
{
Divide(9, 2);
Divide(4, 0);
}
catch(int expn)
{
cout<<"second catch"<<endl;
}
return 0;
}
몫: 4
나머지: 1
first catch
second catch