Data+

12. 클래스 템플릿의 이해3

by Qerogram

* 싱글톤 템플릿 클래스

- 상속을 이용해서 만들 수 있으며, 어떠한 객체가 꼭 하나만 있어야 되는 경우 싱글톤으로 정의해야 된다.

- 어떤 클래스의 Instance가 꼭 하나만 생성되도록 하며, 전역적인 접근을 가능하게 한다(static을 이용)

- Base Class를 Template을 이용해 만들며, 이것을 상속 받는 클래스에서 Template Param에 상속받은 클래스를 사용하게 하면 구현이 가능하다.


# 특징

- 오직 1개만 만들수 있는 클래스

- Protected이상의 생성자.

- 복사와 대입을 금지한다.

- Instance를 1개 Return해주는 static member method.


# 활용이 무궁무진하게 많다고 하며, 매니저 클래스 등에도 사용이 가능하고 현업에서 가장 많이 사용.

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
#include <iostream>
 
using namespace std;
 
template <typename T>
class MySingleton {
  public :
  MySingleton() { }
  virtual ~MySingleton() {}
  static T* GetSingleton() {
    if(NULL == _Singleton) _Singleton = new T;
    return ( _Singleton );
  }
  static void Release() {
    delete _Singleton;
    _Singleton = NULL;
  }
  
  private :
    static T* _Singleton;
};
 
template <typename T> T* MySingleton<T> :: _Singleton= NULL;
 
class MyObject : public MySingleton<MyObject> {
  public :
    MyObject() : _nValue(10) {}
    void SetValue(int Value) { _nValue = Value; }
    int GetValue() const { return _nValue; }
  private :
    int _nValue;
};
 
int main() {
  MyObject* MyObj1 = MyObject::GetSingleton();
  cout << MyObj1->GetValue() << endl;
  MyObject* Myobj2 = MyObject::GetSingleton();
  Myobj2->SetValue(20);
  cout << MyObj1->GetValue() << endl;
  cout << Myobj2->GetValue() << endl;
  return 0;
}
cs

* 결과

10
20
20


* Class Template Coding Style 개선.

- 마지막으로 다듬는 작업이다.(선언과 정의를 분리)

- 클래스 템플릿 이해1과 2에서 했던 Stack Template Class를 쪼개 보겠다.

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
#include <iostream>
 
using namespace std;
 
template<typename T> class Stack {
  public :
    explicit Stack(int size);
    ~Stack();
    void Clear();
    int Count() const;
    bool IsEmpty() const;
    int GetStackSize() const;
    bool push(T data);
    T pop();
  private:
    T* m_aData;
    int m_Count;
    int m_Size;
};
 
template <typename T> Stack<T>::Stack(int size) {
  m_Size = size;
  m_aData = new T[m_Size];
  Clear();
}
 
template <typename T> Stack<T>::~Stack() {
  delete[] m_aData;
}
 
template <typename T> void Stack<T>::Clear() {
  m_Count = 0;
}
 
template <typename T> int Stack<T>::Count() const{
  return m_Count;
}
 
template <typename T> bool Stack<T>::IsEmpty() const {
  return 0 == m_Count ? true : false;
}
 
template <typename T> int Stack<T>::GetStackSize() const {
  return m_Size;
}
 
template <typename T> bool Stack<T>::push(T data) {
  if(m_Count >= m_Size) return false;
  m_aData[m_Count++= data;
  return true;
}
 
template <typename T> T Stack<T>::pop() {
  if(m_Count < 1return 0;
  --m_Count;
  return m_aData[m_Count];
}
 
int main() {
  Stack<int> a(5);
  cout << "스택의 크기는 : " << a.GetStackSize() << endl;
  return 0;
}
cs


* 결과

스택의 크기는 : 5


* 책에서는 아래와 같이 작업하면 정의와 선언을 다른 파일에 할수있다고 한다.

inl확장자는 inline의 약자로, 3D 게임에 사용한다고 한다.

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
// stack.h 파일
template<typename T>
class Stack
{
public:
 
 void Clear();
 
};
#include <iostream> 
#include "stack.hpp"
 
// stack.inl 파일
template < typename T >
void Stack<T>::Clear()
{
 std::cout << "Clear() "<< std::endl;
}
// stack.cpp 파일
 
#include "stack.h"
void main()
{
 Stack<int> k;
 k.Clear();
cs


* 참고 : Thinking About C++ STL Programming

'코딩 > C&C++' 카테고리의 다른 글

14. STL list2  (0) 2017.04.16
13. STL list1  (0) 2017.04.15
11. 클래스 템플릿의 이해2  (0) 2017.04.15
10. 클래스 템플릿의 이해1  (0) 2017.04.14
9. 함수 템플릿의 이해2  (0) 2017.04.13

블로그의 정보

Data+

Qerogram

활동하기