16-1. 보조자료템플릿 (Template) 함수템플릿 클래스템플릿 Jong Hyuk Park
함수템플릿 Jong Hyuk Park
함수템플릿소개 함수템플릿 한번의함수정의로서로다른자료형에대해적용하는함수 예 int abs(int n) return n < 0? -n : n; double abs(double n) 함수 return n < 0? -n : n; // 정수형인수의 abs() 함수 // double 형인수의 abs() 함수의인수와반환형의자료형만이다르고함수내부의프로그램코드는모두같음 템플릿함수를사용하여함수정의는한번만하고필요시자료형에따라각각적용 3
함수템플릿정의 함수템플릿은 template 키워드, typename( 또는 class) 템플릿자료형인수들를선언 템플릿의자료형이되어템플릿함수의가인수나반환형을위한자료형으로사용 template <typename Type1 [, typename Type 2 ]> 반환형함수명 ( 가인수리스트 ) 함수호출시에사용되는실인수, 반환형의자료형을컴파일러가템플릿함수의자료형인수에대입하여특정함수를생성하고호출 4
함수템플릿사용예 template <class T> T abs(t n) // T 형가인수, 반환형을갖는템플릿함수 abs() 정의 return n < 0? n : n; main() int i = abs(123); double d = abs(-123.45); // int abs(int n) 을생성하고호출 // double abs(double n) 을생성하고호출 => 함수호출시에사용된실인수, 반환형의자료형에따라두개의 abs() 함수를생성하고호출 int abs(int n) return n < 0? n : n; double abs(double n) return n < 0? n : n; // int i = abs(123); 호출시생성 // double d = abs(-123.45); 호출시생성 5
템플릿자료형인수사용예 템플릿함수의정의시사용되는템플릿의자료형인수는함수의가인수로최소한한번이상사용되어야함 template <typenamet> T func1(t *a); // 올바름 template <typename T> T func2(t a, T b); // 올바름 template <typename T, typename T> T func2(t a, T b); // 에러, T가중복선언 template <typename T, typename U> T func2(t a, U b); // 올바름 template <typename T, typename U, typename V> U func2(t a, V b); // 에러, U가가인수로사용되지않음 6
함수템플릿사용예 1 template <typename Type> Type min(type a, Type b) return a < b? a : b; // 템플릿함수 min() 정의 int main() // int min(int,int) 템플릿함수생성, 호출 cout << min(88,24) << endl; // double min(double,double) 템플릿함수생성및호출 cout << min(1.234,7.56) << endl; 24 1.234 min(88,24) 의호출시에템플릿의자료형인수 Type 이 int 로치환된 int min(int, int) 인함수가 생성되고, min(1.234, 7.56) 의호출시에는 double min(double, double) 인함수가생성 7
함수템플릿사용예 2 template <typename T> // 함수템플릿정의 void ShowData(T a, T b) cout<<a<<endl; cout<<b<<endl; template <typename T1, typename T2> // 함수템플릿정의 void ShowData(T1 a, T2 b) cout<<a<<endl; cout<<b<<endl; int main(void) ShowData(1, 2); ShowData(3, 2.5); //! error int main(void) ShowData(1, 2); ShowData(3, 2.5); 8
함수템플릿의특수화 template <typename T> // 함수템플릿정의 int SizeOf(T a) return sizeof(a); int main(void) int i=10; double e=7.7; char* str="good morning!"; cout<<sizeof(i)<<endl; cout<<sizeof(e)<<endl; cout<<sizeof(str)<<endl; template <typename T> // 함수템플릿정의 int SizeOf(T a) return sizeof(a); template<> // 함수템플릿정의 int SizeOf(char* a) return strlen(a); int main(void) int i=10; double e=7.7; char* str="good morning!"; cout<<sizeof(i)<<endl; cout<<sizeof(e)<<endl; cout<<sizeof(str)<<endl; 9
클래스템플릿 Jong Hyuk Park
클래스템플릿 클래스템플릿 한번의클래스정의로서로다른자료형에대해적용하는클래스 class Counter int value; public: Counter(int n) value = n; Counter() value = 0; int val() return value; void operator ++() ++value; void operator --() --value; ; class Counter double value; public: Counter(double n) value = n; Counter() value = 0; double val() return value; void operator ++() ++value; void operator --() --value; ; 11
클래스템플릿정의및생성 template <typename Type1 [, typename Type 2 ]> class 클래스명 클래스명 < 자료형 [, 자료형, ]> 객체명 ; template <typename T> class Counter T value; public: Counter(T n) value = n; Counter() value = 0; T val() return value; void operator ++() ++value; void operator --() --value; Counter <int> oi; Counter <double> od; 12
클래스템플릿사용예 1 template <typename T> class Counter T value; public: Counter(T n) value = n; Counter() value = 0; T val() return value; void operator ++() ++value; void operator --() --value; ; int main(void) Counter <int> icnt; Counter <double> dcnt(3.14); Counter <char> ccnt('c'); ++icnt; --dcnt; ++ccnt; cout << "++icnt : " << icnt.val() << endl; cout << "--dcnt : " << dcnt.val() << endl; cout << "++ccnt : " << ccnt.val() << endl; template <typename T> class Counter T value; public: Counter(T n); Counter() value = 0; T val(); void operator ++(); ++value; void operator --() --value; ; template <typename T> Counter<T>::Counter(T n) value = n; template <typename T> T Counter<T>::val() return value; int main(void) Counter <int> icnt; Counter <double> dcnt(3.14); Counter <char> ccnt('c'); 13 ++icnt; --dcnt; ++ccnt; cout << "++icnt : " << icnt.val() << endl; cout << "--dcnt : " << dcnt.val() << endl; cout << "++ccnt : " << ccnt.val() << endl;
클래스템플릿사용예 2 template <typename S, typename L> class Size int s; int l; public: Size() s = sizeof(s); l = sizeof(l); void print() cout << s << ',' << l << endl; ; int main(void) Size <char, long int> a; Size <float, double> b; cout << "char,long int: "; a.print(); cout << "float,double : "; b.print(); 14
클래스템플릿의상속 클래스템플릿도일반클래스와같이상속 베이스클래스인클래스템플릿을일반클래스가파생클래스가되어상속받는경우 베이스클래스인클래스템플릿으로부터생성된클래스를상속 클래스템플릿을생성하지않고전체를상속받으면에러 클래스템플릿인베이스클래스로부터클래스템플릿인파생클래스가상속받는경우 template <typename T> class Base ; class Derive : public Base<int> template <typename T> class Base ; template <typename U> class Derive : public Base<U> 15
클래스템플릿의상속예 template <typename T> class Area // 베이스클래스템플릿 T side1, side2; public: 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> // 파생클래스템플릿 public: Rectangle(U s1, U s2) : Area<U>(s1,s2) // 생성자 /* no operation */ U getarea(void) U s1, s2; int main(void) 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 클래스템플릿인파생클래스 Rectangle 이또다른 클래스템플릿인베이스클래스 Area 로부터상속받 는예이다. Rectangle 파생클래스템플릿는 Area 베이스클래스템플릿전체를상속받는다. 16 ; getside(s1,s2); return s1 * s2;