10. 클래스 템플릿의 이해1
by Qerogram* 클래스 템플릿의 필요성을 우선 코드로 보자.
- 기획팀에서, 유저들이 게임에 접속하여 다른 유저들과 게임을 했을 때, 유저들의 경험치가 변경되는 이력을 보고싶다.
즉, 게임이 끝날 때 마다 경험치를 저장하여야 되고, 가장 최신에서 가장 오래된 순(LIFO)로 보여주어야 하니 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 | #include <iostream> using namespace std; const int MAX_EXP_COUNT = 100; class ExpStack { public : ExpStack() { Clear(); } void Clear() { m_Count = 0; } int Count() const { return m_Count; } bool IsEmpty() { return 0 == m_Count ? true : false; } bool push(float Exp) { if(m_Count > MAX_EXP_COUNT) return false; m_aData[m_Count] = Exp; ++m_Count; return true; } float pop() { if(m_Count < 1) return 0.0f; --m_Count; return m_aData[m_Count]; } private : float m_aData[MAX_EXP_COUNT]; int m_Count; }; int main() { ExpStack kExpStack; cout << "첫번째 게임 종료 - 경험치 145.5f" << endl; kExpStack.push(145.5f); cout << "두번째 게임 종료 - 경험치 183.25f" << endl; kExpStack.push(183.25f); cout << "세번째 게임 종료 - 경험치 162.3f" << endl; kExpStack.push(162.3f); int Count = kExpStack.Count(); for(int i = 0 ; i < Count; ++i) cout <<"현재 경험치 -> " << kExpStack.pop() << endl; return 0; } | cs |
* 결과
첫번째 게임 종료 - 경험치 145.5f
두번째 게임 종료 - 경험치 183.25f
세번째 게임 종료 - 경험치 162.3f
현재 경험치 -> 162.3
현재 경험치 -> 183.25
현재 경험치 -> 145.5
- 이번에는, 돈 변경 이력을 보고싶다고 하여, 또 아래와 같이 만들었다.
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 | #include <iostream> using namespace std; const int MAX_MONEY_COUNT = 100; class MoneyStack { public : MoneyStack() { Clear() } void Clear() { m_Count = 0; } int Count() const { return m_Count; } bool push(int Money) { if(m_Count >= MAX_MONEY_COUNT ) return false; m_aData[m_Count] = Money; ++m_Count; return true; } int pop() { if(m_Count < 1) return 0; --m_Count; return m_aData[m_Count] ; } private: int m_aData[MAX_MONEY_COUNT]; int m_Count; }; | cs |
- 얼추 이런 식의 코드가 나오게 되는데, ExpStack Class와 몹시 유사하다. 이러한 경우 Template을 이용하자.
* Class Template 문법
template <typename type> class 클래스 이름
ex) template <typename T> class Stack { ... };
* Stack Class를 Class Template으로 정의를 해본다면,
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 | #include <iostream> using namespace std; const int MAX_COUNT = 100; template <typename T> class Stack { public : Stack() { Clear(); } void Clear() { m_Count = 0; } int Count() const { return m_Count; } bool IsEmpty() const { return 0 == m_Count ? true : false; } bool push(T data) { if(m_Count >= MAX_COUNT) return false; m_aData[m_Count++] = data; return true; } T pop() { if(m_Count < 1) return 0; m_Count--; return m_aData[m_Count]; } private : T m_aData[MAX_COUNT]; int m_Count; }; int main() { Stack<double> kStackExp; cout << "첫번째 게임 종료 - 현재 경험치 145.5f" << endl; kStackExp.push(145.5f); cout <<"두번재 게임 종료 - 현재 경험치 183.25f" << endl; kStackExp.push(183.25f); cout <<"세번째 게임 종료 - 현재 경험치 162.3f" << endl; kStackExp.push(162.3f); int Count = kStackExp.Count(); for(int i =0; i < Count; ++i) { cout << "현재 경험치 ->" << kStackExp.pop() << endl; } cout << endl << endl; Stack<int> kStackMoney; cout << "첫번째 게임 종료 - 현재 돈 1000023" << endl; kStackMoney.push(1000023); cout << "두번째 게임 종료 - 현재 돈 1000234" << endl; kStackMoney.push(1000234); cout << "세번째 게임 종료 - 현재 돈 1000145" << endl; kStackMoney.push(1000145); Count = kStackMoney.Count(); for(int i = 0; i < Count; ++i) { cout << "현재 돈 -> " << kStackMoney.pop() << endl; } return 0; } | cs |
*결과
첫번째 게임 종료 - 현재 경험치 145.5f
두번재 게임 종료 - 현재 경험치 183.25f
세번째 게임 종료 - 현재 경험치 162.3f
현재 경험치 ->162.3
현재 경험치 ->183.25
현재 경험치 ->145.5
첫번째 게임 종료 - 현재 돈 1000023
두번째 게임 종료 - 현재 돈 1000234
세번째 게임 종료 - 현재 돈 1000145
현재 돈 -> 1000145
현재 돈 -> 1000234
현재 돈 -> 1000023
* Class Template에서 Non-type Parameter 사용.
- 바로 앞에서 Stack Class를 정의했을 땐, 저장할 수 있는 공간이 100개로 한정되어 있는데, 공간의 크기가 변경될 수 있어야 사용하기에 적합하다. 고로, Function Template때 하였던 None-Type으로 하면 해결이 된다.
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 | #include <iostream> using namespace std; template <typename T, int Size> class Stack { public : Stack() { Clear(); } void Clear() { m_Count=0; } int Count() const { return m_Count; } bool IsEmpty() const { return 0 == m_Count ? true : false; } int GetStackSize() const { return Size; } bool push(T data) { if(m_Count >= Size) return false; m_aData[m_Count++] = data; return true; } T pop() { if(m_Count < 1) return 0; --m_Count; return m_aData[m_Count]; } private : T m_aData[Size]; int m_Count; }; int main() { Stack<int, 100> kStack1; cout << "스택의 크기는 ? " << kStack1.GetStackSize() << endl; Stack<double, 60> kStack2; cout << "스택의 크기는 ? " << kStack2.GetStackSize() << endl; return 0; } | cs |
* 결과
스택의 크기는 ? 100
스택의 크기는 ? 60
* 참고 - Thinking about C++ STL Programming
'코딩 > C&C++' 카테고리의 다른 글
12. 클래스 템플릿의 이해3 (0) | 2017.04.15 |
---|---|
11. 클래스 템플릿의 이해2 (0) | 2017.04.15 |
9. 함수 템플릿의 이해2 (0) | 2017.04.13 |
8. 함수 템플릿의 이해1 (0) | 2017.04.13 |
7. Merge sort(합병정렬) (0) | 2017.04.10 |
블로그의 정보
Data+
Qerogram