제14장 예외처리와 템플릿 예외 처리의 개요를 학습한다. 예외 처리를 적용할 수 있다. 템플릿의 개념을 이해한다. 템플릿으로 간단한 클래스를 설계할 수 있다.
이번 장에서 만들어 볼 프로그램 (1) 한사람이 먹을 수 있는 피자 조각 개수를 계산하는 프로그램을 작성하자. 사람 수를 0 으로 입력하여도 오류가 일어나지 않게 한다. (2) 템플릿을 사용하여서 어떤 자료형도 저장할 수 있는 Box 클래스를 작성하고 실험해보 자.
예외처리란?
예제 int main() { int pizza_slices = 0; int persons = -1; int slices_per_person = 0; cout << "피자 조각수를 입력하시오: "; cin >> pizza_slices; cout << "사람수를 입력하시오: "; cin >> persons; slices_per_person = pizza_slices / persons; cout << "한사람당 피자는 " << slices_per_person << "입니다." << endl; return 0; }
예외처리기
try-catch 블록
예제 int main() { int pizza_slices = 0; int persons = -1; int slices_per_person = 0; try cout << "피자 조각수를 입력하시오: "; cin >> pizza_slices; cout << "사람수를 입력하시오: "; cin >> persons;
예제 if (persons == 0) throw persons; slices_per_person = pizza_slices / persons; cout << "한사람당 피자는 " << slices_per_person << "입니 다." << endl; } catch (int e) { cout << "사람이 " << e << " 명 입니다. " << endl; return 0;
try/catch 블록에서의 실행 흐름
catch 블록의 매개 변수
타입이 일치되는 예외만 처리된다. try { int person =0; ... if (persons == 0) throw persons; } catch(char e) { cout << "사람이 " << e << " 명 입니다. "<< endl;
예외 전달
예제 #include <iostream> using namespace std; int dividePizza(int pizza_slices, int persons); int main() { int pizza_slices = 0; int persons = 0; int slices_per_person = 0; try cout << "피자 조각수를 입력하시오: "; cin >> pizza_slices; cout << "사람수를 입력하시오: "; cin >> persons; slices_per_person = dividePizza(pizza_slices, persons); cout << "한사람당 피자는 " << slices_per_person << "입니 다." << endl; }
예제 catch (int e) { cout << "사람이 " << e << " 명 입니다. " << endl; } return 0; int dividePizza(int pizza_slices, int persons) if (persons == 0) throw persons; return pizza_slices / persons;
표준예외 C++ 표준 라이브러리에서 예외가 발생하면 std::exception이라는 특별한 예외가 발생하며 <exception>헤더에 정의된다.
예제 #include <iostream> #include <exception> using namespace std; int main() { try { int* p = new int[100000]; delete p; } catch (exception& e) { cout << "표준 예외가 발생했습니다. " << e.what() << endl; return 0;
다중 catch 문장 try { cout << "피자 조각수를 입력하시오: "; cin >> pizza_slices; cout << "사람수를 입력하시오: "; cin >> persons; if (persons < 0) throw "negative"; // 예외 발생! if (persons == 0) throw persons; // 예외 발생! slices_per_person = pizza_slices / persons; cout << "한사람당 피자는 " << slices_per_person << "입니 다." << endl; } catch (const char *e) { cout << "오류: 사람수가 " << e << "입니다" << endl; catch (int e) { cout << "오류: 사람이 " << e << " 명입니다." << endl;
실행결과
구체적인 예외를 먼저 잡는다. try { getIput(); } catch(TooSmallException e) {
함수 템플릿 C++에서도 하나의 형틀을 만들어서 다양한 코드를 생산 해 내도록 할 수 있는데 이것을 템플릿이라고 한다. 함수 템플릿(function template)은 함수를 찍어내기 위한 형틀 이다.
일반화 프로그래밍(generic programming) template<typename T> T get_max(T x, T y) { if( x > y ) return x; else return y; }
일반화 프로그래밍(generic programming)
예제 #include <iostream> using namespace std; template <typename T> T get_max(T x, T y) { if (x > y) return x; else return y; } int main() cout << get_max(1, 3) << endl; cout << get_max(1.2, 3.9) << endl; return 0;
함수 템플릿과 함수 오버로딩 #include <iostream> using namespace std; template <typename T> void swap_values(T& x, T& y) { T temp; temp = x; x = y; y = temp; }
함수 템플릿과 함수 오버로딩 void swap_values(char* s1, char* s2) { int len; len = (strlen(s1) >= strlen(s2)) ? strlen(s1) : strlen(s2); char* tmp = new char[len + 1]; strcpy(tmp, s1); strcpy(s1, s2); strcpy(s2, tmp); delete[] tmp; }
함수 템플릿과 함수 오버로딩 int main() { int x = 100, y = 200; swap_values(x, y); // x, y가 모두 int 타입- OK! cout << x << " " << y << endl; char s1[100] = "This is a first string"; char s2[100] = "This is a second string"; swap_values(s1, s2); // s1, s2가 모두 배열 - 오버로딩 함수 호출 cout << s1 << " " << s2 << endl; return 0; }
두개의 타입 매개 변수를 같는 함수 템플릿 template<typename T1, typename T2> void copy(T1 a1[], T2 a2[], int n) { for (int i = 0; i < n; ++i) a1[i] = a2[i]; }
예제 #1 template<typename T> void copy_array(T a[], T b[], int n) { for (int i = 0; i < n; ++i) a[i] = b[i]; }
예제 #2 template <typename T> T get_first(T[] a) { return a[0]; }
클래스 템플릿
클래스 템플릿
예제 #include <iostream> using namespace std; template <typename T> class Box { T data; // T는 타입(type)을 나타낸다. public: Box() { } void set(T value) { data = value; } T get() { return data; };
예제 int main() { Box<int> box; box.set(100); cout << box.get() << endl; Box<double> box1; box1.set(3.141592); cout << box1.get() << endl; return 0; }
두개 이상의 타입 매개 변수를 가지는 경우
예제 #include <iostream> using namespace std; template <typename T1, typename T2> class Box2 { T1 first_data; // T1은 타입(type)을 나타낸다. T2 second_data; // T2는 타입(type)을 나타낸다. public: Box2() { } T1 get_first(); T2 get_second(); void set_first(T1 value) { first_data = value; } void set_second(T2 value) { second_data = value; };
예제 template <typename T1, typename T2> T1 Box2<T1, T2>::get_first() { return first_data; } T2 Box2<T1, T2>::get_second() { return second_data; int main() { Box2<int, double> b; b.set_first(10); b.set_second(3.14); cout << "(" << b.get_first() << ", " << b.get_second() << ")" << endl; return 0;
Q & A