[C++] Template
programming/cpp

[C++] Template


C++은 일반화 프로그래밍


템플릿은 원래 C++ 표준이 아니었고 일반화 프로그래밍 표준이었는데

원래 템플릿 쓰던 애들이 가져와서 C++에서 쓰는거다.


구표준까지는 따로였지만, 신표준으로 넘어가면서 '템플릿도 C++이야' 라고 선언하면서

템플릿이 C++에 흡수되고, 그걸 표준화시킨게 STL(Standard Template Library)다.


얘는 일반화 프로그래밍이라 타입을 정할 수 없다.


1. C++에는 2가지 템플릿이 있다.

1. 템플릿 함수(외부함수를 템플릿으로 만들겠다 이거야)

2. 템플릿 클래스


VS 01_ 코드참고)

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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
1. 동적 바인딩에서 Stack and Queue를
Template으로 만들어서 어떤 타입이든 쓸 수 있게 만들어라
*/
 
#define ARR_MAX        2
#define ARR_MIN        0
#include <iostream>
#include <string>
using namespace std;
 
template <typename T>
class vPop {
protected:
    T temp;        // Pop 연산을 할 때 리턴할 값을 임시로 저장하는 임시 필드
public:
    virtual void Pop() = 0;
};
 
template <typename T>
class Memory : public vPop<T> {
protected:
    T *arr;        // T 타입의 메모리 동적 할당에 쓰이는 포인터    
    int top;    // top과 front는 배열의 위치를 알려주는 카운트 변수이므로 무조건 int
public:
    Memory()    // 생성자
    {
        top = -1;
        arr = new T[ARR_MAX];
    }
    
    // push and pop operation
    void Push(T data)
    {
        // 만약 메모리가 꽉 찼다면
        if (top + >= ARR_MAX)        isFull();
 
        // 메모리에 넣을 공간이 있다면
        else {
            system("cls");
            cout << "┌───────────────────────┐" << endl;
            cout << "│Push할 값을 입력하세요.│" << endl;
            cout << "└───────────────────────┘" << endl;
            cout << "==> ";
            cin >> vPop<T>::temp;
 
            this->top++;                // 탑 변수 이동(ex. from index -1 to index 0)
            arr[top] = vPop<T>::temp;    // 배열에 데이터를 넣음
 
            cout << "-------------------------" << endl;
            cout << "Push push babay~" << endl;
            cout << "-------------------------" << endl;
        }
    }
    virtual void Pop() = 0;
    void isFull() {
        cout << "-------------------------" << endl;
        cout << "Hey man~ Memory stack overflow!" << endl;
        cout << "-------------------------" << endl;
    }
    int isEmpty() {
        if (Memory::top < 0) {
            cout << "Hey man~ Memory stack underflow!" << endl;
            cout << "-------------------------" << endl;
            return 1;
        }
        return 0;
    }
};
 
template <typename T>
class MyStack : public Memory<T> {
public:
    MyStack()
    {}
    void Pop()
    {
        if (!isEmpty()) {
            // pop한 값을 temp에 넣고 return 한다.
    //        vPop<T>::temp(p[Memory<T>::top]);
            cout << "Pop한 값 : " << arr[top--<< endl;
    //        return vPop<T>::temp();
        }
        else {
            return;
        }
    }
};
 
//template <typename T>
//class MyQueue : public Memory<T> {
//    T *p;
//    int front;
//public:
//    // constructor
//    MyQueue();
//
//    // setter and getter
//    void setFront(int front) { this->front = front; }
//    int getFront() { return this->front; }
//
//    virtual T Pop();
//};
 
//template <typename T>
//MyQueue<T>::MyQueue()
//{
//    p = NULL;
//    front = 0;
//}
//T MyQueue<T>::Pop()
//{
//    p = Memory<T>::getArr();
//
//    // pop한 값을 temp에 넣고 return 한다.
//    if (!isEmpty()) {
//        temp = p[MyQueue<T>::getFront()];
//
//        // shift 작업(해야함)
//        for (T i = 0; i < Memory<T>::getRear(); i++) {
//            p[i] = p[i + 1];
//        }
//        setRear(getRear() - 1);
//
//        return temp;
//    }
//    else {
//        return -9;
//    }
//}
 
void main()
{
    Memory<string> *mem;
    MyStack<string> s;
    string data;
 
    // 아래의 변수들은 일종의 스위치이므로 int로 고정
    int button;            // 자료 구조 버튼 변수
    int PushOrPop = 0;    // Push or Pop 버튼 변수
    int sayYesOrNo = 0;    // "계속하시겠습니까?" 버튼 변수
    int check = -9;        // 예외 처리 false 변수
 
    do {
        cout << "┌───────────────────────┐" << endl;
        cout << "│자료 구조를 선택하세요.│" << endl;
        cout << "└───────────────────────┘" << endl;
        cout << "1. Stack" << endl;
        cout << "2. Queue" << endl;
        cout << "3. Exit" << endl;
        cout << "-------------------------" << endl;
        cin >> button;
 
        if (button == 1) { mem = &s; }    // dynamic binding
//        else if (button == 2) { mem = &q; }
        else if (button == 3) {
            cout << "-------------------------" << endl << "프로그램을 종료합니다." << endl;
            cout << "빠이루!" << endl << "-------------------------" << endl;
            return;
        } else {
            cout << "-------------------------" << endl << "잘못된 번호를 입력했습니다." << endl;
            cout << "다시 입력하세요." << endl << "-------------------------" << endl;
            continue;
        }
 
        system("cls");
        cout << "┌─────────────────────────┐" << endl;
        cout << "│수행할 기능을 선택하세요.│" << endl;
        cout << "└─────────────────────────┘" << endl;
        cout << "1. Push Operation" << endl;
        cout << "2. Pop Operation" << endl;
        cout << "3. Back to menu" << endl;
        cout << "-------------------------" << endl;
        cin >> PushOrPop;
 
        switch (PushOrPop)
        {
        case 1:
            mem->Push(data);
            break;
        case 2:    // pop 연산
            mem->Pop();
            //cout << "-------------------------" << endl;
            //if (check != (data = mem->Pop()))
            //{
            //    cout << "값 : " << data << endl;
            //    cout << "-------------------------" << endl;
            //}
            break;
        default:
            break;
        }
 
        cout << "계속하시겠습니까?" << endl;
        cout << "1. Yes" << "\t" << "2. No" << endl;
        cout << "-------------------------" << endl;
        cin >> sayYesOrNo;
 
    } while (sayYesOrNo == 1);
}
cs