3. 예외 발생 예외 처리
–프로그램 실행에서 예외가 발생한 경우에 대한 처리 과정
–예외 처리가 없는 경우 정상적인 프로그램 실행이 안될 수도 있음
3/14
4. 4/14
소스 14-1 (ch14_01.cpp)
#include <iostream>
using namespace std;
int main()
{
int number1, number2;
int quotient, reminder;
cout << "수1 : ";
cin >> number1;
cout << "수2 : ";
cin >> number2;
quotient=number1/number2;
reminder=number1%number2;
cout << "몫 : " << quotient << endl;
cout << "나머지 : " << reminder << endl;
return 0;
}
number2의 값을 0으로 입력한 경우 프로그램 실행이 정상적으로 되지 않음!!!
5. 5/14
소스 14-2 (ch14_02.cpp) number2의 값이 0일 경우에 대한 처리 코드 포함
#include <iostream> using namespace std; int main() { int number1, number2; int quotient, reminder; cout << "수1 : "; cin >> number1; cout << "수2 : "; cin >> number2; if (number2==0) { cout << number1 << "은 0으로 나눌 수 없습니다!!" << endl; return 1; } quotient=number1/number2; reminder=number1%number2; cout << "몫 : " << quotient << endl; cout << "나머지 : " << reminder << endl; return 0; }
6. 예외처리 try와 catch 1 C++은 예외처리 블록을 제공
6/14
try
{
예외 발생 여부를 확인해서 발생할 경우 throw 전달인수;
예외가 발생하지 않은 경우 수행할 내용
}
catch (throw에서 전달받은 인수)
{
예외가 발생했을 때 수행할 내용
}
7. 예외처리 try와 catch 2 try 블록
–정상적인 처리 과정
–예외 발생시 throw 명령 실행 catch 블록으로 제어 이동함 catch
–예외 처리 과정
–throw 명령으로 전달된 매개변수 처리
7/14
9. 9/14
소스 14-4 (ch14_04.cpp) : 함수에서 예외 블록 호출하기 1
#include <iostream>
using namespace std;
double Average(const int total, const int num)
{
if (total<0 || num==0)
throw num;
return total/(double)num;
}
int Sum(const int score1, const int score2, const int score3)
{
if (score1<0 || score2<0 || score3<0)
throw 3;
return score1+score2+score3;
}
두 함수 모두 try 블록에서 호출됨
10. 10/14
소스 14-4 (ch14_04.cpp) : 함수에서 예외 블록 호출하기 2
int main()
{
int kor=-100, eng=99, math=98;
int total=0;
double aver;
try
{
total=Sum(kor, eng, math);
cout << "합 : " << total << endl;
}
catch (int i)
{
cout << "*************************************" << endl;
cout << i << "개의 과목점수는 0보다 커야 합니다!!!" << endl;
}
Sum() 함수의 throw에 의해 제어가 첫번째 catch 블록으로 이동될 수 있음
11. 11/14
소스 14-4 (ch14_04.cpp) : 함수에서 예외 블록 호출하기 3
try
{
aver=Average(total, 0);
cout << "평균 : " << aver << "**" << aver << endl;
}
catch(int n)
{
cout << "#####################################" << endl;
cout << "과목 수는 " << n << "보다 커야 합니다!!!" << endl;
}
return 0;
}
Average() 함수의 throw에 의해 제어가 두번째 catch 블록으로 이동될 수 있음
12. 예외 처리 정보를 함수 선언에 넣기 함수 선언에서 throw 덧붙이기!!
12/14
int Total(const int k, const int e, const int m); 함수에 예외처리를 덧붙이면 int Total(const int k, const int e, const int m) throw (char *);
예외처리 정보를 함수 선언에 넣는 것에 대해 Visual C++ 컴파일러에서 정확하게 지원하고 있지 않음
이를 해결하기 위해
#pragma warning (disable : 4290)
을 프로그램 코드에 삽입하기 바람
13. 13/14
소스 14-5 (ch14_05.cpp) : 함수 선언에서 예외처리 코드 포함하기 1
#include <iostream> #pragma warning( disable : 4290 ) using namespace std; int Total(const int k, const int e, const int m) throw(char *); double Average(const int s, const int num) throw(char *); int main() { int kor=-100, eng=99, math=98; int total=0; double aver; try { total=Total(kor, eng, math); aver=Average(total,0); cout << "합 : " << total << endl; cout << "평균 : " << aver << endl; }
14. 14/14
소스 14-5 (ch14_05.cpp) : 함수 선언에서 예외처리 코드 포함하기 2
catch (char *msg)
{
cout << "*************************************" << endl;
cout << msg << endl;
}
return 0;
}
int Total(const int k, const int e, const int m) throw(char *)
{
if (k<0 || e<0 || m<0)
throw "과목 점수는 0보다 커야 합니다";
return k+e+m;
}
double Average(const int s, const int num) throw(char *)
{
if (s<0 || num<=0)
throw "잘못된 매개변수입니다.";
return s/(double)num;
}
15. 표준 예외 클래스 exception 클래스, exception 클래스를 상속한 여러 파생 클래스들~
–exception.h
–자주 발생하는 예외처리를 포함함
•bad_alloc – new 연산에 의해 발생한 예외처리
•bad_cast – dynamic_cast 연산에 의해 발생한 예외처리 등
15/14
16. 16/14
소스 14-6 (ch14_06.cpp)
#include <iostream>
#include <exception>
using namespace std;
int main()
{
try
{
for (int i=1; i<=100; i++)
{
new int[70000000];
cout << i << "번째 배열이 생성되었습니다." << endl;
}
}
catch (bad_alloc &e)
{
cout << "Exception : " << e.what() << endl;
}
return 0;
}
실행 결과 1번째 배열이 생성되었습니다. 2번째 배열이 생성되었습니다. 3번째 배열이 생성되었습니다. 4번째 배열이 생성되었습니다. 5번째 배열이 생성되었습니다. 6번째 배열이 생성되었습니다. Exception : bad allocation
17. 예외 클래스
17/14
예외 클래스
예외 객체 생성시점
관련 내용
runtime_error
실행 오류, <stdexcept>
파생 클래스 :
overflow_error, underflow_error
bad_alloc
메모리 할당 오류
new
bad_cast
형변환 오류
dynamic_cast
bad_type_id
typeid에 대한 피 연산자가 널 포인터인 경우
typeid
bad_exception
예기치 못한 처리
함수 발생 목록에 있지 않은 예외
bad_logic_error
클래스 논리 오류, <stdexcept>
파생 클래스 : invalid_argument, length_error, out_of_range
18. 사용자 예외 클래스 표준 예외 클래스를 상속 받아 사용자 예외 클래스 정의
18/14
업무 처리 클래스 - 멤버 함수 내에서 예외가 발생할 경우 throw로 예외 객체 생성하여 catch 블록으로 제어 이동
업무 처리 예외 클래스
-멤버 변수나 멤버 함수를 통해 예외 처리 내용을 포함함
19. 실습
19/14
세 과목의 성적 처리 클래스와 성적 처리로 인한 예외 사항을 사용자 예외 클래스로 정의해 보자.
class Sung
{
public:
Sung();
Sung(const int kor, const int eng, const int math);
int GetTotal();
double GetAver();
private :
int kor, eng, math,total;
double aver;
};
class SungException : public logic_error { public : SungException(const int total, const int num); int GetTotal(); int GetNum(); private : int total, num; };
20. 20/14
소스 14-7, 14-8 (ch14_sung.h, ch14_sung.cpp)
int Sung::GetTotal() { if (kor<=0 || eng<=0 || math<=0) throw SungException(total, 3); //예외 객체 생성하여 전달 total=kor+eng+math; return total; } double Sung::GetAver() { if (total<0) throw SungException(total, 3); //예외 객체 생성하여 전달 aver=total/(double)3; return aver; }
SungException::SungException(const int total, const int num)
: logic_error("잘못된 인수값") //기반 클래스 생성자 호출
{
this->total=total;
this->num=num;
}
24. 함수 템플릿 함수 템플릿
–함수의 처리 절차는 동일하나 처리 대상이 상황에 따라 여러 자료형일 경우 함수 오버로딩으로 정의할 경우 대상 자료형 개수 만큼의 함수 정의가 있어야 함
–함수 템플릿은 함수 내에서 사용하는 자료형을 일반화된 유형으로 정의하여 하나의 함수를 정의하고 함수 호출에서 적절한 자료형을 대입해서 사용
24/9
25. 함수 템플릿 구현 함수의 헤더(함수 선언과 함수 정의)에 일반화된 자료형 명시 두 개의 수 중에서 큰 값을 리턴하는 함수
template<typename 일반화유형이름>
함수 선언 : template<typename T> T MaxValue(const T num1, const T num2);
함수 정의 : template<typename T> T MaxValue(const T num1, const T num2) { if (num1>num2) return num1; else return num2; }
25/9
26. 소스 15-1 (ch15_01.cpp)
#include <iostream>
using namespace std;
template<typename T>
T MaxValue(const T num1, const T num2)
{
if (num1>num2)
return num1;
else
return num2;
}
int main()
{
cout << "정수 비교 결과 : " << MaxValue(3, 5) << endl;
cout << "배정도 비교 결과 : " << MaxValue(9.1, 3.6) << endl;
return 0;
}
26/9
27. 클래스 템플릿 1 클래스 내에 사용되는 자료형을 일반화 유형으로 표기 클래스의 멤버 변수나 멤버 변수의 반환 자료형 등을 일반화 유형으로 사용할 수 있음
클래스 선언
클래스 멤버 함수 정의
template<typename 일반화유형이름>
class 클래스이름
{
…..
};
template<typename 일반화유형이름>
리턴형 클래스이름<일반화유형이름>::멤버함수(매개변수)
{
…..
}
27/9
28. 클래스 템플릿 2 클래스 멤버 함수 정의에서 생성자를 포함해서 매번 일반화 유형을 함수 머리 부분 위에 명시해야 함 객체 생성시 일반화 유형 명시 해야 함 클래스 템플릿은 클래스 템플릿 자체가 선언의 의미가 있어 클래스 선언과 정의가 하나의 파일에 있어야 함!!!
클래스이름 <일반화유형에 대치될 자료형> 객체이름;
28/9
29. 소스 15-2 (ch15_sung.h)
#ifndef _SUNG_H_
#define _SUNG_H_
#include <iostream>
using namespace std;
template<typename T>
class SUNG
{
public :
SUNG(const T k, const T e, const T m);
T GetSum();
double GetAver();
private :
T k,e,m,sum;
double aver;
};
template<typename T> SUNG<T>::SUNG(const T k, const T e, const T m) { this->k=k; this->e=e; this->m=m; } template<typename T> T SUNG<T>::GetSum() { sum=k+e+m; return sum; } template<typename T> double SUNG<T>::GetAver() { aver=sum/(double)3; return aver; } #else #endif
29/9