Collection(container) 객체
[Stack, Linked_list, tree, 등등 .. 의 자료구조에서 무엇인가 담는다는 의미를 가진 대부분의 것들]
Collection 에서 안에 담는 성질에 따라서 어떤 형태인지 달라짐
[ex) Stack에 int형을 넣게끔 만들었다.. 하면 그건 integer형 Stack이다.]
그런데 쓰다보니.. int형을 넣기위해 구현한 Stack으로 double형을 위한 것도 만들고 싶으면
또 double형을 위한 Stack을 하나더 구현을 해주어야하고 또 만들고나니
char형도 넣어주고 싶으니.. 또 Stack을 또 구현을 해주어야 한다.
그렇게 만들어주다보니
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //integer형 Stack class Stack { private: int *_s; int *_top; int _size; private: void initialize(); void overflowError(); void emptyError(); public: Stack(int n=MAX); void push(int item); int pop(); int peek(); void reset(); bool isEmpty(); }; | cs |
| | |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //double형 Stack class DStack { private: double *_s; double *_top; int _size; private: void initialize(); void overflowError(); void emptyError(); public: DStack(int n=MAX); void push(double item); double pop(); double peek(); void reset(); bool isEmpty(); }; | cs |
|
위처럼 하나하나 타입에 따라 전부다 만들어주어야 한다
이처럼 참 귀찮고 힘든일을 해결해주기 위하여 C++ 3.0에서 나타난것이
STL(Standard Template Library) 에서 나타난다
여기서 각종 자료구조(list, stack, queue 등등)에서
list<int> / list<char> / stack<int> 이런식으로 사용이 가능하게끔 만들어준다.
이가 생성되는 방식이
macro expansion (매크로 확장) 방식을 이용한다.(매크로 확장 :: 컴파일시에 ~ )
ㄴ 주의! ) 소스코드를 모두 .h(헤더파일)에 한번에 작성을 해야한다
여기서 template 방식을 이용하는 방식은 타입을 변수라고 생각하고 사용을 하게 해주는 방법이다.
바로 클래스 선언하기 바로위에 template<class T>
해준뒤 클래스 선언 후 내부 소스내용들을
따로 cpp에 만들던 방식으로 밑에 쭉 적어주면 된다.
그렇게해서 만들어진 코드는 (Stack 기준 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #if !defined(_STACK_H) #define _STACK_H #define MAX (100) #define NIL (0) template <class Type> // 클래스 선언 하기 바로위에 template를 말해준다. class Stack { private: Type *_s; Type *_top; int _size; private: void initialize(); void overflowError(); void emptyError(); public: Stack(int n=MAX); void push(Type item); Type pop(); Type peek(); void reset(); bool isEmpty(){ if (_top == NIL) return true; else return false; } }; template <class Type> // 각 함수위에도 모두 지정을 해준뒤 사용해야하며 Stack<Type>::Stack(int n) // Stack<Type> 을 네임스페이스로 지정해주어야 한다. { _s = new Type[n]; _size = n; _top = NIL; initialize(); } template <class Type> void Stack<Type>::initialize() { Type *p = _s; for(int i = 0; i < _size; i++) { *p = 0; p++; } } template <class Type> void Stack<Type>::overflowError() { cerr << "Stack overflow error occurs." << endl; exit(-1); } template <class Type> void Stack<Type>::emptyError() { cerr << "Stack empty error occurs." << endl; exit(-1); } template <class Type> void Stack<Type>::push(Type item) { if (_top == NIL) { _top = _s; *_top = item; } else { if ((_top-_s) >= (_size-1)) overflowError(); _top++; *_top = item; } } template <class Type> Type Stack<Type>::pop() { if (_top == NIL) emptyError(); Type value = *_top; if (_top == _s) { _top = NIL; } else { _top--; } return(value); } template <class Type> Type Stack<Type>::peek() { if (_top == NIL) emptyError(); return *_top; } template <class Type> void Stack<Type>::reset() { _top = NIL; initialize(); } #endif // !defined(_STACK_H) | cs |
| | |
이렇게 구현이 된다
클래스 선언 직전에 template <타입명>을/를 선언해주고
필요한 함수들 위에도 사용후
template<type>
클래스명<타입명> :: 함수명()
{
}
이런식으로 사용을 해야한다.
좀더 자세한내용은 조금더 공부하고 적겠습니다!