예제로배우는 C++ 객체지향프로그래밍 1 템플릿 (template) 이란? 한번의정의로모든자료형에대한처리를하도록고안 처리내용은같으나자료형이다를경우각자료형에대한함수를별도작성해야함 이때템플릿으로함수나클래스를통합정의 각자료형을일반화하여하나의모델로모든자료형을처리 예제로배우는 C++ 객체지향프로그래밍 2
템플릿함수 예제로배우는 C++ 객체지향프로그래밍 3 템플릿함수 템플릿함수 (template function) 한번의함수정의로서로다른자료형에대해적용하는함수 템플릿함수가적용되어야하는예 int abs(int n) // 정수형인수의 abs() 함수 return n < 0? -n : n; double abs(double n) // double 형인수의 abs() 함수 return n < 0? -n : n; 함수의매개변수와반환형의자료형만이다르고함수내부의프로그램코드는모두같음 템플릿함수를사용하여함수정의는한번만하고필요시자료형에따라각각적용가능 예제로배우는 C++ 객체지향프로그래밍 4
템플릿함수정의 템플릿함수는 template 키워드와 typename( 또는 class) 으로템플릿자료형매개변수들를선언 typename 으로선언된템플릿자료형은템플릿함수의형식매개변수나반환형을위한자료형으로사용 template <typename 식별자 [,typename 식별자...]> 함수선언 ; 또는 template <class 식별자 [class [,class 식별자...]> 함수선언 ; 함수호출시에사용되는실매개변수, 반환형의자료형을컴파일러가템플릿함수의자료형인수에대입하여특정함수를생성하고호출 예제로배우는 C++ 객체지향프로그래밍 5 템플릿함수사용예 T abs(t n) // T 형가인수, 반환형을갖는틀함수 abs() 정의 return n < 0? n : n; int i = abs(123); double d = abs(-123.45); // int abs(int n) 을생성하고호출 // double abs(double n) 을생성하고호출 => 함수호출시에사용된실인수, 반환형의자료형에따라두개의 abs() 함수를생성하고호출 int abs(int n) // int i = abs(123); 호출시생성 return n < 0? n : n; double abs(double n) // double d = abs(-123.45); 호출시생성 return n < 0? n : n; 예제로배우는 C++ 객체지향프로그래밍 6
예제 7.1: 템플릿함수사용예 1 #include <iostream> template <typename Type> Type minimum(type i a, Type b) // 템플릿함수 minimum( ) 정의 return a < b? a : b; // int minimum(int,int) int) 템플릿함수생성, 호출 cout << minimum(88,24) << endl; // double minimum(double,double) 템플릿함수생성및호출 cout << minimum(1234756) minimum(1.234,7.56) << endl; 24 1.234 예제로배우는 C++ 객체지향프로그래밍 7 예제 7.2: 템플릿함수사용예 2 #include <iostream> template <typename T1, typename T2> void outdata(t1 a, T2 b) cout << a << ',' << b << endl; // void outdata(int, int) 템플릿함수생성, 호출 outdata(11,22); // void outdata(double, char) 템플릿함수생성, 호출 outdata(3.14, 'c'); c); 11,22 3.14,c 템플릿함수의매개변수가여러개이고유형도다른예이다. 예제로배우는 C++ 객체지향프로그래밍 8
템플릿함수의특수화 템플릿함수를사용하는자료형중특정자료형에대해별도취급 템플릿함수정의다음에 template<> 라고쓰고특정자료형에대하여템플릿함수와같은명칭의함수를별도정의 예제로배우는 C++ 객체지향프로그래밍 9 #include <iostream> template <typename Type> Type minimum(type a, Type b) // 템플릿함수 minimum( ) 정의 return a < b? a : b; template< > double minimum(double a,double b) // 템플릿함수의특수화 return a > b? a : b; // 큰값을반환 // int minimum(int,int) 템플릿함수생성, 호출 int n = minimum(88,24); i cout << "n = " << n << endl; // 특수화템플릿함수 //double minimum(double,double) double) 생성및호출 double d = minimum(3.65,7.56); cout << "d = " << d << endl; 예제로배우는 C++ 객체지향프로그래밍 10 예제 7.3: 템플릿함수의특수화 n = 24 d = 756 7.56
템플릿함수오버로딩 템플릿함수간의오버로딩 일반함수의오버로딩과마찬가지로매개변수의자료형, 매개변수의갯수등으로구분 템플릿함수와일반함수간오버로딩도가능 예제로배우는 C++ 객체지향프로그래밍 11 // sum( ) 템플릿함수 1 정의 T sum(t a, T b) returna+b; // sum( ) 템플릿함수 2 정의 T sum(t *array,int size) T s = 0; for (int i=0; i < size; i++) s += array[i]; return s; int a[10]; for (int i=0; i < 10; ++i) a[i] = i*i; double x=2.1, y = 12.5; cout << "sum 1 : " << sum(x,y) << endl; // 템플릿함수 1 생성, 호출 cout << "sum 2 : " << sum(a,10) << endl; // 템플릿함수 2 생성, 호출 예제로배우는 C++ 객체지향프로그래밍 12 예제 7.4: 템플릿함수의오버로딩예 sum 1:146 14.6 sum 2 : 285
템플릿클래스 예제로배우는 C++ 객체지향프로그래밍 13 템플릿클래스 템플릿함수와유사하게클래스를일괄적으로정의 클래스의멤버변수나멤버함수의자료형이다른클래스들을하나의템플릿으로구성 class Counter int value; Counter(int n) value = n; Counter() value=0; int val() return value; void operator ++() ++value; void operator --() --value; ; class Counter double value; Counter(double n) value = n; Counter() value=0; double val() return value; void operator ++() ++value; void operator --() --value; ; 예제로배우는 C++ 객체지향프로그래밍 14
템플릿클래스정의및생성 template <typename 식별자 [,typename 식별자...]> 클래스선언 ; 또는 template <class 식별자 [,class 식별자...]> 클래스선언 ; 템플릿 _ 클래스명 < 자료형 [, 자료형, ]> 객체 _ 식별자 ; class Counter T value; Counter(T n) value = n; Counter() value = 0; T val() return value; void operator ++() ++value; void operator --() --value; ; Counter <int> oi; Counter <double> od; 예제로배우는 C++ 객체지향프로그래밍 15 #include <iostream> class Counter // 템플릿클래스정의 T value; Counter( ) value = 0; Counter(T n) value = n; T val( ) return value; void operator ++( ) ++value; void operator --( ) --value; ; Counter <int> icnt; // int형 Counter 클래스생성 Counter <double> dcnt(3.14); // double 형 Counter 클래스생성 Counter <char> ccnt('c'); // char형 Counter 클래스생성 예제로배우는 C++ 객체지향프로그래밍 16 예제 7.5: 템플릿클래스사용예 1 ++icnt; --dcnt; t;++ ++ccnt; cout << "++icnt : " << icnt.val( ) << endl; cout << "--dcnt : " << dcnt.val( ) << endl; cout << "++ccnt : " << ccnt.val( ) << endl; ++icnt : 1 --dcnt : 2.14 ++ccnt : D
#include <iostream> template <typename S,typename L> class Size int s; int l; Size( ) s = sizeof(s); l = sizeof(l); void print( ) cout << s << ',' << l << endl; ; 예제 7.6: 템플릿클래스사용예 2 char, long int: 1, 4 float, double : 4, 8 Size <char,long int> a; Size <float,double> b; cout << "char,long int: "; a.print( ); cout << "float,double : "; b.print( ); 예제로배우는 C++ 객체지향프로그래밍 17 순천향대학교 #include 컴퓨터학부 <iostream> class Array T *p; // 배열의시작주소 int size; // 배열의크기 Array(int num); // 생성자 T &operator [ ](int i); // [ ] 연산자중복 ; Array<T>::Array(int num) // 템플릿클래스생성자외부정의 p = new T[num]; if (!p) // 동적메모리할당에러 cout << "!! Allocation error n"; exit(1); size = num; T &Array<T>::operator [ ](int i) // 템플릿클래스멤버함수외부정의 if (i <0 i >= size) cout << " n!! Array bounds error n"; exit(1); 예제로배우는 C++ 객체지향프로그래밍 18 예제 7.7: 템플릿클래스사용예 3(1) return p[i]; // p[i] 의참조자반환 Array <int> n(10); // int형 Array 클래스생성 Array <double> d(10); // double형 Array 클래스생성 for (int i = 0; i < 10; i++) n[i] = 2*i; d[i] = 0.2*i; for (int j = 0; j<11; i++) cout << n[j] << ':'; cout << d[j]<< ' '; cout << endl;
예제 7.7: 템플릿클래스사용예 3(2) 0:0 2:0.2 4:0.4 6:0.6 8:0.8 10:1 12:1.2 14:1.4 16:1.6 18:1.8!! Array bounds error 예제로배우는 C++ 객체지향프로그래밍 19 템플릿클래스의특수화 템플릿클래스에서특정자료형을별도취급 템플릿함수와마찬가지로특수화함 template <> 클래스선언 ;
순천향대학교 #include 컴퓨터학부 <iostream> class mycontainer T element; mycontainer (T arg) element=arg; T increase () return ++element; ; // 템플릿클래스의특수화 template < > class mycontainer <char> char element; mycontainer (char arg) element=arg; char uppercase ( ) if ((element>='a') && (element<='z')) element+='a'-'a'; return element; ; 예제로배우는 C++ 객체지향프로그래밍 21 예제 7.8: 템플릿클래스특수화의예 int main (void) mycontainer<int> myint (7); mycontainer<char> mychar ('j'); cout << myint.increase( ) << endl; cout << mychar.uppercase( ) << endl; 8 J 디폴트템플릿매개변수 템플릿매개변수에디폴트값을정의 템플릿클래스의객체선언시템플릿에전달되는자료형을생략할경우디폴트매개변수로선언된자료형의값을적용 예제로배우는 C++ 객체지향프로그래밍 22
#include <iostream> 예제 7.9: 디폴트템플릿매개변수의예 template <typename T = int, typename U = double> class Var_Type T x; U y; Var_Type( ) : x(11), y(22) //!! 수정 Var_Type(T a, U b) x = a, y = b; void Show_Type( ) cout << " x=" << x << endl; cout << " y = " << y << endl; ; 예제로배우는 C++ 객체지향프로그래밍 23 int main (void) x = 10 y=314 3.14 x = k y = 1.2 x = 11 y = 22 Var_Type< > type1(10, 3.14); Var_Type<char> type2('k', 1.2); Var_Type<> type3; type1.show_type( ); type2.show_type( ); type3.show_type(); //!! 수정 템플릿클래스의오버로딩 템플릿클래스내에멤버함수정의시특정자료형에대해적용할수없을경우 별도의멤버함수정의필요 특정자료형에대해멤버함수오버로딩
#include <iostream> class Cmp T a; T b; Cmp(T x, Ty)a=x;b=y; = y; T max( ) return a > b? a : b; T min( ) return a < b? a : b; // char * 형 max( ),min( ) 멤버함수오버로딩 char *max(char *s1, char *s2) return strcmp(s1,s2) > 0? s1 : s2; char *min(char *s1, char *s2); ; 예제 7.10: 템플릿클래스멤버함수오버로딩예 Cmp <int> a(24,7); Cmp <char *> s("hello","world"); cout << a.min( ) << endl; cout << s.max("hello","world") " " ld") << endl; // char * 형 min( ) 멤버함수클래스외부정의 char *Cmp<char *>::min(char *s1, char *s2) return strcmp(s1,s2) < 0? s1 : s2; 예제로배우는 C++ 객체지향프로그래밍 25 7 world 템플릿클래스의상속 틀클래스도일반클래스 class Base 와같이상속 일반클래스의템플릿클래스상속 템플릿클래스의템플릿클래스상속 ; class Derive : public Base<int> class Base ; template <typename U> class Derive : public Base<U> 순천향대학교정보기술공학부 26
#include <iostream> 예제 7.11: 템플릿클래스의상속예 1 // 베이스템플릿클래스 class Base T x; Base(T m) x = m; void showx( ) cout << "x = " << x << ' n'; ; class Derive : public Base<int> // 파생클래스 int y; // 생성자, 템플릿클래스생성자호출 Derive(int m,int n) : Base<int>(m) y = n; void showy( ) cout << "y = " << y << ' n'; 예제로 ; 배우는 C++ 객체지향프로그래밍 27 Derive d(10,20); dshowx(); d.showx( d.showy( ); x = 10 y = 20 순천향대학교 #include 컴퓨터학부 <iostream> class Area // 베이스템플릿클래스 T side1, side2; Area(T s1, T s2) // 생성자 side1 = s1; side2 = s2; void getside(t &s1, T &s2) s1 = side1; s2 = side2; ; template <typename U> class Rectangle : public Area<U> // 파생템플릿클래스 Rectangle(U s1, U s2) : Area<U>(s1,s2) s2) // 생성자 /* no operation */ U getarea(void) U s1, s2; getside(s1,s2); return s1 * s2; 예제로배우는 C++ 객체지향프로그래밍 28 ; 예제 7.12: 템플릿클래스의상속예 2 Rectangle <int> ir(3,14); Rectangle <double> dr(2.5, 7.3); cout << "int area : " << ir.getarea( ()<< endl; cout << "double area : " << dr.getarea( ) << endl; int area : 42 double area : 18.25
응용예 예제로배우는 C++ 객체지향프로그래밍 29 집합프로그램버전 4(1) 집합프로그램버전 4 버전 3의 List와 Set 클래스를템플릿클래스로수정하여정수, 실수, 문자들의집합정의가가능하도록템플릿적용 // 템플릿구조체 Node 정의 struct Node // 노드의정의 // List 템플릿클래스정의 class List // 베이스클래스 // Set 템플릿클래스정의 class Set : public List<T> // 파생클래스 예제로배우는 C++ 객체지향프로그래밍 30
집합프로그램버전 4(2) 교재내용중 Union() 함수관련다음코드오류수정 36. void Union(Set *s1, Set *s2);// 두집합의합집합연산함수 171. void Set<T>::Union(Set <T> *s1, Set <T> *s2) 189. Set<T>::insert(n->data); 190. 191. 예제로배우는 C++ 객체지향프로그래밍 31 순천향대학교 1. // 집합프로그램컴퓨터학부버전이4 상정 2. 3. #include <iostream> 4. 5. 6. #define NULL 0 7. 8. // 템플릿구조체 Node 정의 9. struct Node // 노드의정의 10. T data; // 자료 11. Node *next; // 다음노드의위치포인터 12. ; 13. 14. // List 템플릿클래스정의 15. class List // 베이스클래스 16. protected: // 보호부분지정 17. Node <T> *header; 18. 19. List( ) header = NULL; // 생성자 20. ~List( ); // 소멸자 21. virtual bool insert(t val); // 자료삽입함수, 가상함수 22. virtual bool member(t val); // 멤버조사함수, 가상함수 23. bool del(t val); // 자료삭제함수 24. virtual void print( ); // 자료출력함수, 가상함수 25. ; 26. 27. 28. class Set : public List<T> // 파생클래스 29. int num; // 집합의원소수 30. 31. Set( ) num = 0; // 생성자 32. bool member(t e); // 원소 e의멤버조사함수 33. bool insert(t e); // 원소 e의삽입함수 34. void remove(t e); // 원소 e의삭제함수 35. 예제로bool 배우는equal(Set C++ 객체지향 *s); // 프로그래밍두집합의등가여부조사함수32 36. void Union(Set *s1, Set *s2); // 두집합의합집합연산함수 37. void print( ); // 집합의원소출력함수 38. ; 39. 40. 41. List<T>::~List( ) // 베이스클래스소멸자 42. 43. Node <T> *n n, *tmp; 44. 45. n = header; 46. if (n == NULL) // 빈리스트 47. return; 48. 49. while (n!= NULL) // 리스트의끝이아니면반복 50. tmp = n; // 현재노드지정 51. n = n->next; // 다음노드지정 52. delete tmp; // 현재노드메모리해제 53. 54. 55. 56. 57. bool List<T>::insert(T insert(t val) // 베이스클래스 insert( ) 함수 58. 59. Node <T> *tmp; 60. 61. if ((tmp=new Node<T>) == NULL) // 삽입될자료의새노드지정 62. return false; // 동적메모리할당실패시 false 반환 63. tmp->data = val; 64. tmp->next = header; // 삽입전첫노드를새노드의다음으로지정 65. header = tmp; // 새노드를첫노드로지정 66. return true; 67. 68.
순천향대학교 69. template 컴퓨터학부 <typename이t> 상정 70. bool List<T>::member(T val) // 베이스클래스 member( ) 함수 71. 72. Node <T> *n; 73. 74. n = header; 75. while (n!= NULL) // 리스트의끝이아니면반복 76. if (n->data == val) //val 이멤버이면 77. return true; 78. n=n->next; 79. 80. return false; 81. 82. 83. 84. bool List<T>::del(T val) 85. 86. Node <T> *before; // 삭제할노드의앞노드포인터 87. Node <T> *current; // 삭제할노드 88. 89. if (header!= NULL) // 빈리스트가아니면 90. before = current = header; 91. while (current->data!= val) // 삭제노드를발견시 까지반복 92. before = current; 93. current = current->next; 94. if (current == NULL) 95. cout << val << " is not found n"; 96. return false; 97. 98. 99. if (before == current) // 삭제할노드가첫노드이 면 100. header = header->next; // 삭제다음노드를첫 노드로예제로지정배우는 C++ 객체지향프로그래밍 33 101. delete current; // 삭제노드의메모리해제 102. 103. else 104. before->next = current->next; 105. // 앞노드가삭제노드다음을가리키도록지정 106. delete current; // 삭제노드의메모리해제 107. 108. return true; 109. 110. else // 빈리스트이면에러메시지출력 111. cout << "Null list(delete) n"; 112. return false; 113. 114. 115. 116. 117. void List<T>::print( ) 118. 119. Node <T> *n; 120. 121. n = header; 122. if (n == NULL) // 빈리스트이면에러메시지출력 123. cout << "Null list(print) n"; 124. return; 125. 126. while (n!= NULL) // 리스트의끝이아니면반복 127. cout << n->data << " "; // 자료출력 128. n = n->next; // 다음노드로이동 129. 130. 131. 132. 133. bool Set<T>::member(T e) // 파생클래스 member( ) 함수 134. 135. return List<T>::member(e); // 베이스제 7클래스장템플릿 memebr( ) 함수호출 순천향대학교 136. 컴퓨터학부 137. 138. 139. bool Set<T>::insert(T e) // 파생클래스 insert( ) 함수 140. 141. if (!List<T>::member(e) && List<T>::insert(e)) 142. // 베이스클래스함수호출 143. // e가연결리스트멤버가아니면서자료가삽입되 면 144. ++num; 145. return true; 146. 147. return false; 148. 149. 150. 151. void Set<T>::remove(T e) 152. 153. if (List<T>::del(e)) // 베이스클래스의 del( ) 함수호 출 154. --num; 155. 156. 157. // 두집합의등가여부조사함수 158. 159. bool Set<T>::equal(Set <T> *s) 160. 161. if (num!= s->num) // 원소의수가같지않으면 162. return false; // false 반환 163. for (Node <T> *n = header; n!= NULL; n = n->next) 164. if (!s->member(n->data)) // 원소중하나라도집 합 s의멤버가아니면 165. return false; // false 반환 166. return true; // 위의경우가아니면 true 반환 167. 168. 예제로배우는 C++ 객체지향프로그래밍 34 169. // 두집합의합집합연산함수 170. 171. void Set<T>::Union(Set <T> *s1, Set <T> *s2) 172. 173. Node <T> *n, *tmp; 174. n = header; 175. 176. // 현재객체의노드들을제거 177. while (n!= NULL) // 리스트의끝이아니면반복 178. tmp = n; // 현재노드지정 179. n = n->next; // 다음노드지정 180. delete tmp; // 현재노드해제 181. 182. 183. for (n = s1->header; n!= NULL; n = n->next) 184. List<T>::insert(n->data); // 현재객체에 s1 원소복사 185. num = s1->num; 186. 187. for (n = s2->header; n!= NULL; n = n->next) 188. // s2 원소삽입 189. Set<T>::insert(n->data); 190. 191. 192. 193. 194. // 집합의원소출력함수 195. 196. void Set<T>::print( ) 197. 198. cout << ''; 199. List<T>::print( ); // 베이스클래스 print( ) 함수호출 200. cout << " n"; 201. 202.
집합프로그램버전 4 203. 204. 205. Set <char> cs; 206. cs.insert('a'); cs.insert('d'); cs.insert('x'); cs.insert('c'); 207. cs.remove('x'); 208. cout << "1. cs = "; cs.print( ); 209. 210. Set <int> s1,s2,s3; 211. s1.insert(88); s1.insert(33); s1.insert(99); s1.insert(77); 212. s2.insert(10); s2.insert(20); s2.insert(30); 213. s3.union(&s1, &s2); 214. cout << "2. s1 = "; s1.print( ); 215. cout << "3. s2 = "; s2.print( ); 216. cout << "4. s3 = s1 U s2 = "; s3.print( ); 217. 218. Set <double> ds; 219. ds.insert(1.2); ds.insert(3.14); ds.insert(7.777); 220. cout << "5. ds = "; ds.print( ); 221. if (ds.member(3.14)) 222. cout << "6. 3.14 is in set ds n"; 223. 224. 225. 1. cs = c d a 2. s1 = 77 99 33 88 3. s2=302010 20 4. s3 = s1 U s2 = 10 20 30 88 33 99 77 5. ds = 7.777 3.14 1.2 6. 3.14 is in set ds 예제로배우는 C++ 객체지향프로그래밍 35 과제 1 - 필수과제 연습문제 7.1 두수를교환하는 swap(a, b) 템플릿함수를작성하여라. 단, a, b는문자, 정수, 실수형의자료로표현될수있다. 7.2 연습문제 7.1의 swap(a,b) 템플릿함수에서문자열의자료형도교환할수있도록수정하여라. 76 7.6 예제 713 7.13 의프로그램에예제 67 6.7 과같이삼각형의면적을계산하는파생클래스 Triangle을추가하여라. 예제로배우는 C++ 객체지향프로그래밍 36
과제 2 - 선택과제 응용예문제 71 7.1 응용예 7.1의집합프로그램버전4에두집합간의교집합을구하는멤버함수 intersect() 와한집합이다른집합의부분집합관계인가를판정하는멤버함수 subset() 을삽입하라. 예제로배우는 C++ 객체지향프로그래밍 37