C++ 프로그래밍 입문 14장 예외 처리 에러 처리 예외 처리의 개념적 이해 예외 처리 구문 throw문과 다중 예외 처리 핸들러의 사용 예외 처리 클래스 throw문의 전달과 응용 new 연산자의 예외 처리 함수가 전달할 수 있는 예외의 제한
C++ 프 그래밍 입문
14장 처
에러 처
처 의 개념적 이해
처 문
throw문과 다 처 핸들러의 사
처 클래스
throw문의 전달과 응
new 연산자의 처
함수가 전달할 수 있는 의 제한
14장 처 1
1. 에러 처
에러
n 컴파일 시간 에러 : 주 문법 에러
n 실행 시간 에러 : 실행 발견 는 에러, 주 논 에러
Ø : 산술 연산 시 0으 나누 에러
에러 처
n 실행 발생할 수 있는 논 적 에러 측하고 이 발견 및 처 하는
드 추가하는 것int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
cout << "사칙 연산 종료" << endl;
return 0;}
에러 발생
가능!
14장 처 2
1. 에러 처
if 문을 이 한 0으 나누 에 한 에러 처
int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
if (y == 0) // 에러 처cout << "0 나눌 수는 없습니다." << endl;
else {cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
}
cout << "사칙연산 종료" << endl;
return 0;}
14장 처 3
2. 처 의 개념적 이해
처
n 프 그램의 정상적인 흐
에 위배 는 상황
에 한 처
Ø 상황 : 문제 다 또는
프 그래 다 다 게 해
수 있음
Ø 1 : 0으 나누
à 에러
Ø 2 : 본 문제의 경 x, y
0 이상이 한다는
제 조건이 있음
처 의 본 개념
n 정상적인 수행 흐 과
처 을 하는
것
int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
if (y == 0) goto error;
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
cout << "사칙연산 종료" << endl;
return 0;
error :cout << "0 나눌 수는 없습니다." << endl;cout << "사칙연산 종료" << endl;
return 0;}
상황 감
à 처 이동
처
14장 처 4
3. 처 문
처 문의 조 : try, throw, catch 문
n try 블 : 가 발생할 것으 상 는 역
n throw 문 : 가 발생할 경 전달(호출)
n catch 블 : 처 핸들러
14장 처 5
3. 처 문
처 문의 사
int main(void){
int x, y;
cout << "2개 실수 : ";cin >> x >> y;
try { // try 블 : 감시if (y == 0)
throw y; // throw문 : 전달
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
}catch (int a) { // catch 블 : 처
cout << "0 나눌 수는 없습니다." << endl;}
cout << "사칙연산 종료" << endl;
return 0;}
호출
à함수 호출과 유사
14장 처 6
3. 처 문
처 문의 수행 흐
throw 문 이 자동으
감 할 수는 을 ?
음!
à 처 클래스
라이브러 만든다
사 자 측 에 는
자동으 감 하는
것처럼 사 가능
à 5, 6절 참고
14장 처 7
4. throw문과 다 처 핸들러의 사
throw문을 한 값의 전달
n 타입 : int, char, char *, double, 클래스 등 든 타입 가능
n 값이 전달 을 수 있음
n 여러 개의 처 핸들러(catch문) 작 가능à 타입에 라 수행
n 전달 타입의 값을 처 할 수 있는 처 핸들러(catch문)가 다 ?
à terminate 함수가 수행 (VC++의 경 프 그램 종료)
n 든 타입의 값을 처 할 수 있는 처 핸들러 작 가능
Ø catch (…) { }
다 처 핸들러 작
int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
14장 처 8
4. throw문과 다 처 핸들러의 사
다 처 핸들러 작 (계 )
try {if (y == 0)
throw 1;
if (x <= 0 || y <= 0)throw 1.0;
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
}catch (int a) { // 처 핸들러 : int형
cout << "0 나눌 수는 없습니다." << endl;}catch (double a) { // 처 핸들러 : double형
cout << "x y는 수가 될 수 없습니다." << endl;}catch (...) { // 처 핸들러 : 든 타
cout << " 든 throw문 수 할 수 는 처 핸들러 니다" << endl;}
cout << "사칙연산 종료" << endl;
return 0;}
* 주의 : catch 블 택 방식
드 상의 순 합
여 판단
à catch (…) 블 을 저
위치시킨다 ?
에 있는 블 은 수행
가
à사실은 컴파일 에러
à 5절 처 클래스 참고
14장 처 9
5. 처 클래스
throw 문을 한 클래스 객체의 전달
class CDivideZero {public :
void What() { cout << "0 나눌 수는 없습니다." << endl; } };
class CNegativeNumber {public :
void What() { cout << "x y는 수가 될 수 없습니다." << endl; }};
int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
14장 처 10
5. 처 클래스
throw 문을 한 클래스 객체의 전달 (계 )
try {if (y == 0)
throw CDivideZero(); // CDivideZero 시 객체 전달
if (x <= 0 || y <= 0)throw CNegativeNumber(); // CNegativeNumber 시 객체 전달
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
}catch (CDivideZero a) { // CDivideZero 객체 값에 한 전달 받
a.What();}catch (CNegativeNumber a) { // CNegativeNumber 객체 받
a.What();}catch (...) {
cout << " 든 throw문 수 할 수 는 처 핸들러 니다" << endl;}
cout << "사칙연산 종료" << endl;
return 0;}
수행 내 동일
à하나의 처 핸들러 수행 가능?
à CDivideZero CNegativeNumber의
base 클래스 만든다 …!
14장 처 11
5. 처 클래스
CDivideZero, CNegativeNumber의 base 클래스 만들
n CMyException
class CMyException { // CDivideZero CNegativeNumber base 클래스public :
virtual void What() = 0; // 추상 클래스 만듦. base 클래스 역할만.};
class CDivideZero : public CMyException {public :
void What() { cout << "0 나눌 수는 없습니다." << endl; } };
class CNegativeNumber : public CMyException {public :
void What() { cout << "x y는 수가 될 수 없습니다." << endl; }};
int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
14장 처 12
5. 처 클래스
CDivideZero, CNegativeNumber의 base 클래스 만들 (계 )
try {if (y == 0)
throw CDivideZero();
if (x <= 0 || y <= 0)throw CNegativeNumber();
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
}catch (CMyException &a) { // 제는 CMyException 둘 다 받 수
a.What();}catch (...) {
cout << " 든 throw문 수 할 수 는 처 핸들러 니다" << endl;}
cout << "사칙연산 종료" << endl;
return 0;}
14장 처 13
5. 처 클래스
다음 프 그램 드의 문제점은 무 일 ?
n catch 블 택 방식에 주의
catch (CMyException &a) {// 제는 CMyException 둘 다 받 수
a.What();
}
catch (CDivideZero &a) { // 0 나누기 는 별 처 원함
a.What();
}
catch (...) {
cout << " 든 throw문 수 할 수 는 처 핸들러 니다" << endl;
}
14장 처 14
6. throw문의 전달과 응
첩 try ~ catch 블
int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
try {if (y == 0)
throw 1; // int 값 전달
try { // 중첩 try 문if (x <= 0 || y <= 0)
throw 1.1; // double 값 전달
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
}catch (double a) { // double 값 수
cout << "x y는 수가 될 수 없습니다." << endl;}
}catch (int a) { // int 값 수
cout << "0 나눌 수는 없습니다." << endl;}
cout << "사칙연산 종료" << endl;
return 0;}
해당 try 블 과 match 는 catch문이 값을
수 하 한다 à 에 있는 try ~ catch
블 으 전달
함수 내에 throw문을 처 할 수 있는 catch문이
다 à함수 호출한 함수 throw문이
전달
14장 처 15
6. throw문의 전달과 응
함수 throw문이 전달 는
int main(void){
int x, y;
cout << "2개 정수 : ";cin >> x >> y;
try {if (y == 0)
throw 1;
CheckNegative(x, y); // 함수 호출
cout << "+ : " << x + y << endl;cout << "- : " << x - y << endl;cout << "* : " << x * y << endl;cout << "/ : " << x / y << endl;
}catch (int a) {
cout << "0 나눌 수는 없습니다." << endl;}catch (double a) {
cout << "x y는 수가 될 수 없습니다." << endl;}
cout << "사칙연산 종료" << endl;
return 0;}
bool CheckNegative(int x, int y)
{
if (x <= 0 || y <= 0)
throw 1.1;
return true;
}
는 전달 는가?
14장 처 16
6. throw문의 전달과 응
처 하는 클래스 + throw문의 전달
n 라이브러 만드는 프 그래 : 라이브러 의 문제점 인식
Ø throw 문 작 가능, 그러나 게 처 할 는 의문?
n 라이브러 사 하는 프 그래 : 상황에 한 처 책임
Ø catch 블 작 가능
다음 에 CCalc 클래스 처 클래스들을 라이브러 생각해 보라!
class CMyException {public :
virtual void What() = 0;};
class CDivideZero : public CMyException {public :
void What() { cout << "0 나눌 수는 없습니다." << endl; } };
class CNegativeNumber : public CMyException {public :
void What() { cout << "x y는 수가 될 수 없습니다." << endl; }};
14장 처 17
6. throw문의 전달과 응
class CCalc {
private :
int x, y;
public :
void Input() {
cout << "2개 정수 : ";
cin >> x >> y;
if (y == 0)
throw CDivideZero();
if (x <= 0 || y <= 0)
throw CNegativeNumber();
}
void Output() {
cout << "+ : " << x + y << endl;
cout << "- : " << x - y << endl;
cout << "* : " << x * y << endl;
cout << "/ : " << x / y << endl;
}
};
int main(void)
{
try {
CCalc Calc;
Calc.Input();
Calc.Output();
}
catch (CMyException &a) {
a.What();
}
cout << "사칙연산 종료" << endl;
return 0;
}
라이브러 사 하는 프 그래
입장에 는 throw 문의 사 이
발생 가능한 (타입)에 한
처 만 신경쓰
14장 처 18
7. new 연산자의 처
new 연산자 : 내 적으 함수 수행
à 할당 실패의 경 bad_alloc 발생#include <iostream>#include <new>using namespace std;
int main(void){
int *p;
try {while (1) {
p = new int[100000000];cout << " 할당 공!" << endl;p = NULL;
}}catch (bad_alloc &ex) { // 할당 실패 시 bad_alloc 발생
cout << " 할당 실패!" << endl;cout << ex.what() << endl;
}
if (p != NULL) {cout << " 할당에 공했습니다." << endl;
}else {
cout << " 할당에 실패했습니다." << endl;}return 0;
}
Release 드 실행하는경
14장 처 19
8. 함수가 전달할 수 있는 의 제한
특정 함수 내에 발생(throw)할 수 있는 의 종 제한
n bool CheckNegative(int x, int y) throw(int, double);
Ø CheckNegative 함수 내에 는 int형, double형 값에 한 throw문 발생 가능
n bool CheckNegative(int x, int y) throw();
Ø CheckNegative 함수 내에 는 발생시킬 수 음
정한 타입 이 의 타입에 한 발생 시
n unexpected 함수 수행
현재 VC++에 는
n 의 제한 문법 및 내 을 인식하고는 있 만 컴파일 시 단순히 경고만
발생à 실행은 가능