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

Table of contents


Open source project on GitHub


Jupyter/IPython Notebook


Open API


NoSQL


Jekyll


Gradle


Kotlin


C++

  • C++ keywords
  • 윤성우 열혈강의 C++ 프로그래밍 예제코드 [펼치기]
    1. C언어 기반의 C++ 1
      • printf와 scanf를 대신하는 입출력 방식
      • 함수 오버로딩(Function Overloading)
      • 매개변수의 디폴트 값(Default Value)
      • 인라인 함수(Inline)함수
      • 이름공간(namespace)에 대한 소개
    2. C언어 기반의 C++ 2
      • 새로운 자료형 bool
      • 참조자(Reference)의 이해
      • 참조자(Reference)와 함수
      • maloc & free를 대신하는 new & delete
      • C++에서 C언어의 표준함수 호출하기
    3. 클래스의 기본
      • C++에서의 구조체
      • 클래스(Class)와 객체(Object)
      • 객체지향 프로그래밍의 이해
    4. 클래스의 완성
      • 정보은닉(Information Hiding)
      • 캡슐화(Encapsulation)
      • 생성자(Constructor)와 소멸자(Destructor)
      • 클래스와 배열 그리고 this 포인터
    5. 복사 생성자
      • ‘복사 생성자’ 와의 첫 만남
      • ‘깊은 복사’와 ‘얕은 복사’
      • 복사 생성자의 호출시점
    6. friend와 static 그리고 const
      • const와 관련해서 아직 못다한 이야기
      • 클래스와 함수에 대한 friend 선언
      • C++에서의 static
    7. 상속(Inheritance)의 이해
      • 상속에 들어가기에 앞서
      • 상속의 문법적인 이해
      • protected 선언과 세 가지 형태의 상속
      • 상속을 위한 조건
    8. 상속과 다형성
      • 객체 포인터의 참조관계
      • 가상함수(Vitual Function)
      • 가상 소멸자와 참조자의 참조 가능성
    9. 가상(Virtual)의 원리와 다중상속
      • 멤버함수와 가상함수의 동작원리
      • 다중상속(Multiple Inheritance)에 대한 이해
    10. 연산자 오버로딩 1
      • 연산자 오버로딩의 이해와 유형
      • 단항 연산자의 오버로딩의
      • 교환법칙 문제의 해결
      • cout, cin 그리고 endl의 정체
    11. 연산자 오버로딩 2
      • 반드시 해야 하는 대입 연산자의 오버로딩
      • 배열의 인덱스 연산자 오버로딩
      • 그 이외의 연산자 오버로딩
    12. String 클래스의 디자인
      • C++ 표준과 표즌 string 클래스
      • 문자열 처리 클래스의 정의
    13. 템플릿(Template) 1
      • 템플릿(Template)에 대한 이해와 함수 템플릿
      • 클래스 템플릿(Class Temlpate)
    14. 템플릿(Template) 2
      • Chapter 13에서 공부한 내용의 확장
      • 클래스 템플릿의 특수화(Class Temlpate Specialization)
      • 템플릿의 인자
      • 템플릿과 static
    15. 예외처리(Exception Handling)
      • 예외상황과 예외처리의 이해
      • C++의 예외처리 메커니즘
      • Stack Unwinding(스택 풀기)
      • 예외상황을 표현하는 예외 클래스의 설계
      • 예외처리와 관련된 또 다른 특성들
    16. C++의 형 변환 연산자
      • C++에서의 형 변환 연산

ETC