반응형
출처 : KGCA 게임 아카데미(http://www.kgcaschool.com/). 수업 예제 파일.
OriginalTemplate.h
#pragma once // 어차피 멤버 함수를 클래스 템플릿 외부에 정의해서 다른 파일로 분리할 수 없으니 // 클래스 템플릿 안에다가 인라인으로 넣어버림. // 기본 타입 클래스 템플릿 template <class T> class Bag { T* elem; int size; int max_size; public: void add(T t) { T* tmp; if (size + 1 >= max_size) { max_size *= 2; tmp = new T[max_size]; for (int iCnt = 0; iCnt < size; iCnt++) { tmp[iCnt] = elem[iCnt]; } tmp[size++] = t; delete[] elem; elem = tmp; } else { elem[size++] = t; } } void print() { for (int iCnt = 0; iCnt < size; iCnt++) { cout << elem[iCnt] << " "; } cout << endl << endl; } void sort() { for (int a = 1; a<size; a += 1) { int temp = elem[a]; int b = a - 1; while (b >= 0 && elem[b] > temp) { elem[b + 1] = elem[b]; b -= 1; } elem[b + 1] = temp; } } Bag() : elem(0), size(0), max_size(1) {} }; // 포인터 타입 클래스 템플릿에 대한 부분 특수화 // NULL을 검사하도록 (컬렉션이 수정 및 저장소 유형 template <class T> class Bag<T*> { T* elem; int size; int max_size; public: void add(T* t) { T* tmp; if (t == nullptr) { //check for nullptr cout << "Null pointer!" << endl; return; } if (size + 1 >= max_size) { max_size *= 2; tmp = new T[max_size]; for (int iCnt = 0; iCnt < size; iCnt++) { tmp[iCnt] = elem[iCnt]; } tmp[size++] = *t; //Dereference delete[] elem; elem = tmp; } else { elem[size++] = *t; //Dereference } } void print() { for (int iCnt = 0; iCnt < size; iCnt++) { cout << elem[iCnt] << " "; } cout << endl << endl; } void sort() { for (int a = 1; a<size; a += 1) { int temp = elem[a]; int b = a - 1; while (b >= 0 && elem[b] > temp) { elem[b + 1] = elem[b]; b -= 1; } elem[b + 1] = temp; } } Bag() : elem(0), size(0), max_size(1) {} };
Dictionary.h
#pragma once #include <iostream> #include <string> using namespace std; //클래스 템플릿 template <class key, class value> class dictionary { key* keys; value* values; int size; int max_size; public: void add(key k, value v); void print(); dictionary(int initial_size); }; //클래스 템플릿 부분 특수화 template <class value> class dictionary<int, value> { int* keys; value* values; int size; int max_size; public: void add(int key, value v); void print(); void sort(); dictionary(int initial_size); }; //클래스 템플릿의 멤버 함수를 cpp파일에 따로 정의할 경우 //확인할 수 없는 외부기호라는 링크 에러가 뜬다. //이에 대한 자세한 내용은 템플릿이 클래스를 어떻게 만드는지와 //obj파일이 어떻게 생성되는지에 대해서 확인할 것. //클래스 템플릿 멤버 함수 정의 template<class key, class value> dictionary<key, value>::dictionary(int initial_size) : size(0) { max_size = 1; while (initial_size >= max_size) { max_size *= 2; } keys = new key[max_size]; values = new value[max_size]; } template<class key, class value> void dictionary<key, value>::add(key k, value v) { key* tmpKey; value* tmpVal; if (size + 1 >= max_size) { max_size *= 2; tmpKey = new key[max_size]; tmpVal = new value[max_size]; for (int iCnt = 0; iCnt < size; iCnt++) { tmpKey[iCnt] = keys[iCnt]; tmpVal[iCnt] = values[iCnt]; } tmpKey[size] = k; tmpVal[size] = v; delete[] keys; delete[] values; keys = tmpKey; values = tmpVal; } else { keys[size] = k; values[size] = v; } size++; } template<class key, class value> void dictionary<key, value>::print() { for (int iCnt = 0; iCnt < size; iCnt++) { cout << "{" << keys[iCnt] << ", " << values[iCnt] << "}" << endl; } cout << endl; } //특수화 한 클래스 템플릿 멤버 함수 정의 template <class value> dictionary<int, value>::dictionary(int initial_size) { max_size = 1; while (initial_size >= max_size) { max_size *= 2; } keys = new int[max_size]; values = new value[max_size]; } template <class value> void dictionary<int, value>::add(int key, value v) { int* tmpKey; value* tmpVal; if (size + 1 >= max_size) { max_size *= 2; tmpKey = new int[max_size]; tmpVal = new value[max_size]; for (int iCnt = 0; iCnt < size; iCnt++) { tmpKey[iCnt] = keys[iCnt]; tmpVal[iCnt] = values[iCnt]; } tmpKey[size] = key; tmpVal[size] = v; delete[] keys; delete[] values; keys = tmpKey; values = tmpVal; } else { keys[size] = key; values[size] = v; } size++; } template <class value> void dictionary<int, value>::print() { for (int iCnt = 0; iCnt < size; iCnt++) { cout << "{" << keys[iCnt] << ", " << values[iCnt] << "}" << endl; } cout << endl; } template <class value> void dictionary<int, value>::sort() { int smallest = 0; for (int iCnt = 0; iCnt < size - 1; iCnt++) { for (int jCnt = iCnt; jCnt < size; jCnt++) { if (keys[jCnt] < keys[smallest]) { smallest = jCnt; } } swap(keys[iCnt], keys[smallest]); swap(values[iCnt], values[smallest]); } }
TemplatePartialMain.cpp
#include "Dictionary.h" #include "OriginalTemplate.h" int main() { cout << "한개의 데이터를 받는 경우" << endl << endl; cout << "int형 클래스 생성 및 테스트" << endl; Bag<int> xi; xi.add(8); xi.add(10); xi.add(2); xi.print(); cout << "데이터 정렬" << endl; xi.sort(); xi.print(); cout << "char형 클래스 생성 및 테스트" << endl; Bag<char> xc; xc.add('b'); xc.add('x'); xc.add('e'); xc.print(); cout << "데이터 정렬" << endl; xc.sort(); xc.print(); cout << "uses partial specialization for pointer types." << endl; cout << "int*형 클래스 생성 및 테스트" << endl; Bag<int*> xp; //주소를 받아올 int형 변수 생성 int* p = new int[2]; p[0] = 8; p[1] = 100; int i = 3; int j = 87; int* pn = nullptr; //nullptr 생성 xp.add(&i); xp.add(&j); xp.add(p); xp.add(p+1); xp.add(pn); //들어가지 않음 xp.print(); cout << "데이터 정렬" << endl; xp.sort(); xp.print(); cout << "두개의 데이터를 받는 경우" << endl << endl; cout << "기본 템플릿 클래스 생성 및 테스트" << endl; dictionary<string, string>* dict = new dictionary<string, string>(10); cout << "데이터 한개 입력" << endl; dict->add("apple", "fruit"); dict->print(); cout << "데이터 세개 입력" << endl; dict->add("banana", "fruit"); dict->add("dog", "animal"); dict->print(); cout << "특수화한 템플릿 클래스 생성 및 테스트" << endl; dictionary<int, string>* dict_s = new dictionary<int, string>(10); cout << "데이터 한개 입력" << endl; dict_s->add(100, "apple"); dict_s->print(); cout << "데이터 세개 입력" << endl; dict_s->add(101, "banana"); dict_s->add(89, "dog"); dict_s->add(103 , "cat"); dict_s->print(); dict_s->sort(); cout << "데이터 정렬" << endl; cout << "sorted list :" << endl; dict_s->print(); }
반응형