본문 바로가기
OLD/[C++]개념정리

[개탱][C++][template][Generic class]

by 개탱 2018. 1. 2.
728x90

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 *= _s;
    for(int i = 0; i < _size; i++) {
        *= 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>

클래스명<타입명> :: 함수명()

{


}


이런식으로 사용을 해야한다.


좀더 자세한내용은 조금더 공부하고 적겠습니다!


댓글