14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/cpp14_exception handling.pdf ·...

20
C++ 프로그래밍 입문 14장 예외 처리 에러 처리 예외 처리의 개념적 이해 예외 처리 구문 throw문과 다중 예외 처리 핸들러의 사용 예외 처리 클래스 throw문의 전달과 응용 new 연산자의 예외 처리 함수가 전달할 수 있는 예외의 제한

Upload: others

Post on 03-Mar-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

C++ 프 그래밍 입문

14장 처

에러 처

처 의 개념적 이해

처 문

throw문과 다 처 핸들러의 사

처 클래스

throw문의 전달과 응

new 연산자의 처

함수가 전달할 수 있는 의 제한

Page 2: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;}

에러 발생

가능!

Page 3: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;}

Page 4: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;}

상황 감

à 처 이동

Page 5: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

14장 처 4

3. 처 문

처 문의 조 : try, throw, catch 문

n try 블 : 가 발생할 것으 상 는 역

n throw 문 : 가 발생할 경 전달(호출)

n catch 블 : 처 핸들러

Page 6: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;}

호출

à함수 호출과 유사

Page 7: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

14장 처 6

3. 처 문

처 문의 수행 흐

throw 문 이 자동으

감 할 수는 을 ?

음!

à 처 클래스

라이브러 만든다

사 자 측 에 는

자동으 감 하는

것처럼 사 가능

à 5, 6절 참고

Page 8: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;

Page 9: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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절 처 클래스 참고

Page 10: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;

Page 11: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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 클래스 만든다 …!

Page 12: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;

Page 13: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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;}

Page 14: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

14장 처 13

5. 처 클래스

다음 프 그램 드의 문제점은 무 일 ?

n catch 블 택 방식에 주의

catch (CMyException &a) {// 제는 CMyException 둘 다 받 수

a.What();

}

catch (CDivideZero &a) { // 0 나누기 는 별 처 원함

a.What();

}

catch (...) {

cout << " 든 throw문 수 할 수 는 처 핸들러 니다" << endl;

}

Page 15: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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문이

전달

Page 16: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 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;

}

는 전달 는가?

Page 17: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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; }};

Page 18: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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 문의 사 이

발생 가능한 (타입)에 한

처 만 신경쓰

Page 19: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 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 드 실행하는경

Page 20: 14장예외처리 - contents.kocw.or.krcontents.kocw.or.kr/document/CPP14_Exception Handling.pdf · 14장예외처리 7 4. throw문과다중예외처리핸들러의사용 throw문을통한값의전달

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 의 제한 문법 및 내 을 인식하고는 있 만 컴파일 시 단순히 경고만

발생à 실행은 가능