// 경험치를 저장할 수 있는 최대 개수 const int MAX_EXP_COUNT = 100; // 경험치 저장 스택 클래스 class ExpStack { public: ExpStack() { Clear(); } // 초기화 한다. void Clear() { m_Count = 0; } // 스택에 저장된 개수 int Count() { 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() { // 저장된 것이 없다면 0.0f를 반환한다. if( m_Count < 1 ) { return 0.0f; } // 개수를 하나 감소 후 반환한다. --m_Count; return m_aData[ m_Count ]; } private: float m_aData[MAX_EXP_COUNT]; int m_Count; }; #include실행 결과using namespace std; void 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; } }
// 돈을 저장할 수 있는 최대 개수 const int MAX_MONEY_COUNT = 100; // 돈 저장 스택 클래스 class MoneyStack { public: MoneyStack() { Clear(); } // 초기화 한다. void Clear() { m_Count = 0; } // 스택에 저장된 개수 int Count() { return m_Count; } // 저장된 데이터가없는가? bool IsEmpty() { return 0 == m_Count ? true : false; } // 돈을 저장한다. bool push( __int64 Money ) { // 저장 할 수 있는 개수를 넘는지 조사한다. if( m_Count >= MAX_MONEY_COUNT ) { return false; } // 저장후 개수를 하나 늘린다. m_aData[ m_Count ] = Money; ++m_Count; return true; } // 스택에서 돈을 빼낸다. __int64 pop() { // 저장된 것이 없다면 0을 반환한다. if( m_Count < 1 ) { return 0; } // 개수를 하나 감소 후 반환한다. --m_Count; return m_aData[ m_Count ]; } private: __int64 m_aData[MAX_MONEY_COUNT]; int m_Count; };ExpStack 클래스와 MoneyStack 클래스가 비슷합니다
const int MAX_COUNT = 100; template실행 결과class Stack { public: Stack() { Clear(); } // 초기화 한다. void Clear() { m_Count = 0; } // 스택에 저장된 개수 int Count() { return m_Count; } // 저장된 데이터가 없는가? bool IsEmpty() { return 0 == m_Count ? true : false; } // 데이터를 저장한다. bool push( T data ) { // 저장 할수 있는 개수를 넘는지 조사한다. if( m_Count >= MAX_COUNT ) { return false; } // 저장후 개수를 하나 늘린다. m_aData[ m_Count ] = data; ++m_Count; return true; } // 스택에서 빼낸다. T pop() { // 저장된 것이 없다면 0을 반환한다. if( m_Count < 1 ) { return 0; } // 개수를 하나 감소 후 반환한다. --m_Count; return m_aData[ m_Count ]; } private: T m_aData[MAX_COUNT]; int m_Count; }; #include using namespace std; void main() { Stack 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<__int64> 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; } }
// 템플릿 파라메터중 int Size가 non-type 파라메터입니다. template실행 결과class Stack { public: Stack() { Clear(); } // 초기화 한다. void Clear() { m_Count = 0; } // 스택에 저장된 개수 int Count() { return m_Count; } // 저장된 데이터가 없는가? bool IsEmpty() { return 0 == m_Count ? true : false; } // 데이터를 담을수 있는 최대 개수 int GetStackSize() { return Size; } // 데이터를 저장한다. bool push( T data ) { // 저장할 수 있는 개수를 넘는지 조사한다. if( m_Count >= Size ) { return false; } // 저장 후 개수를 하나 늘린다. m_aData[ m_Count ] = data; ++m_Count; return true; } // 스택에서 빼낸다. T pop() { // 저장된 것이 없다면 0을 반환한다. if( m_Count < 1 ) { return 0; } // 개수를 하나 감소 후 반환한다. --m_Count; return m_aData[ m_Count ]; } private: T m_aData[Size]; int m_Count; }; #include using namespace std; void main() { Stack kStack1; cout << "스택의 크기는?" << kStack1.GetStackSize() << endl; Stack kStack2; cout << "스택의 크기는?" << kStack2.GetStackSize() << endl; }
// 템플릿 파라메터중 int Size가 non-type 파라메터입니다. // Size의 디폴트 값을 100으로 합니다. templateList5에서 템플릿 파라메터 중 Size의 값을 디폴트 100으로 했습니다. 클래스를 생성할 때 두 번째 파라메터 값을 지정하지 않으면 디폴트 값이 사용 됩니다.class Stack { ….. 생략 } void main() { Stack kStack1; cout << "스택의크기는?" << kStack1.GetStackSize() << endl; Stack kStack2; cout << "스택의크기는?" << kStack2.GetStackSize() << endl; }
template실행결과class Stack { public: explicit Stack( int size ) { m_Size = size; m_aData = new T[m_Size]; Clear(); } ~Stack() { delete[] m_aData; } // 초기화 한다. void Clear() { m_Count = 0; } // 스택에 저장된 개수 int Count() { return m_Count; } // 저장된 데이터가 없는가? bool IsEmpty() { return 0 == m_Count ? true : false; } // 데이터를 담을 수 있는 최대 개수 int GetStackSize() { return m_Size; } // 데이터를 저장한다. bool push( T data ) { // 저장할 수 있는 개수를 넘는지 조사한다. if( m_Count >= m_Size ) { return false; } // 저장 후 개수를 하나 늘린다. m_aData[ m_Count ] = data; ++m_Count; return true; } // 스택에서 빼낸다. T pop() { // 저장된 것이 없다면 0을 반환한다. if( m_Count < 1 ) { return 0; } // 개수를 하나 감소 후 반환한다. --m_Count; return m_aData[ m_Count ]; } private: T* m_aData; int m_Count; int m_Size; }; #include using namespace std; void main() { Stack kStack1(64); cout << "스택의 크기는? " << kStack1.GetStackSize() << endl; }
Stack로 클래스를 생성하면 컴파일 에러가 발생합니다.kStack1 = 64;
template <> class 클래스 이름<지정된 타입> { ………………. };아래의 코드는 문자열을 저장하기 위해 char* 으로 전문화한 Stack 클래스입니다.
// ID 문자열의 최대 길이(null 문자포함) const int MAX_ID_LENGTH = 21; // char* 를 사용한 Stack 클래스(List 6) 템플릿 전문화 template<> class Stack실행 결과{ public: explicit Stack( int size ) { m_Size = size; m_ppData = new char *[m_Size]; for( int i = 0; i < m_Size; ++i ) { m_ppData[i] = new char[MAX_ID_LENGTH]; } Clear(); } ~Stack() { for( int i = 0; i < m_Size; ++i ) { delete[] m_ppData[i]; } delete[] m_ppData; } // 초기화한다. void Clear() { m_Count = 0; } // 스택에 저장된 개수 int Count() { return m_Count; } // 저장된 데이터가 없는가? bool IsEmpty() { return 0 == m_Count ? true : false; } // 데이터를 담을 수 있는 최대 개수 int GetStackSize() { return m_Size; } // 데이터를 저장한다. bool push( char* pID ) { // 저장할 수 있는 개수를 넘는지 조사한다. if( m_Count >= m_Size ) { return false; } // 저장 후 개수를 하나 늘린다. strncpy_s( m_ppData[m_Count], MAX_ID_LENGTH, pID, MAX_ID_LENGTH - 1); m_ppData[m_Count][MAX_ID_LENGTH - 1] = "\0"; ++m_Count; return true; } // 스택에서 빼낸다. char* pop() { // 저장된 것이 없다면 0을 반환한다. if( m_Count < 1 ) { return 0; } // 개수를 하나 감소 후 반환한다. --m_Count; return m_ppData[ m_Count ]; } private: char** m_ppData; int m_Count; int m_Size; }; #include using namespace std; void main() { Stack kStack1(64); cout << "스택의 크기는? " << kStack1.GetStackSize() << endl; kStack1.push( 10 ); kStack1.push( 11 ); kStack1.push( 12 ); int Count1 = kStack1.Count(); for( int i = 0; i < Count1; ++i ) { cout << "유저의 레벨 변화 -> " << kStack1.pop() << endl; } cout << endl; char GameID1[MAX_ID_LENGTH] = "NiceChoi"; char GameID2[MAX_ID_LENGTH] = "SuperMan"; char GameID3[MAX_ID_LENGTH] = "Attom"; // Stack 클래스 템플릿의 char* 전문화 버전을 생성한다. Stack kStack2(64); kStack2.push(GameID1); kStack2.push(GameID2); kStack2.push(GameID3); int Count2 = kStack2.Count(); for(int i = 0; i < Count2; ++i) { cout << "같이 게임을 한유저의 ID -> " << kStack2.pop() << endl; } }
template< typename T1, typename T2 > class Test { …. };의 T2를 float로 구체화 하여 부분 전문화를 하면 다음과 같습니다.
template< typename T1 > class Test코드는 다음과 같습니다.{ ….. };
template< typename T1, typename T2 > class Test { public: T1 Add( T1 a, T2 b ) { cout << "일반 템플릿을 사용했습니다." << endl; return a; } }; // T2를 float로 구체화한 Test의 부분 전문화 템플릿 template< typename T1 > class Test{ public: T1 Add( T1 a, float b ) { cout << "부분 전문화 템플릿을 사용했습니다." << endl; return a; } }; #include using namespace std; void main() { Test test1; test1.Add( 2, 3 ); Test test2; test2.Add( 2, 5.8f ); }
template< typename T1, typename T2, typename T3 > class Test { …. };의 부분 전문화 템플릿은
template< typename T1, typename T2 > class Test- 포인터의 부분 전문화{ ….. };
template< typename T > class TestP { …. };의 T의 T* 부분 전문화를 하는 다음과 같습니다.
template< typename T > class TestP코드는 다음과 같습니다.{ …… };
template< typename T > class TestP { public: void Add() { cout << "일반 템플릿을 사용했습니다." << endl; } }; // T를 T*로 부분 전문화 template< typename T > class TestP실행 결과{ public: void Add() { cout << "포인터를 사용한 부분 전문화 템플릿을 사용했습니다." << endl; } }; #include using namespace std; void main() { TestP test1; test1.Add(); TestP test2; test2.Add(); }
#includeusing namespace std; // 파라메터 T를 싱글톤이 되도록 정의 합니다. template 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 T* MySingleton ::_Singleton = NULL; // 싱글톤 클래스 템플릿을 상속 받으면서 파라메터에 본 클래스를 넘깁니다. class MyObject : public MySingleton { public: MyObject() : _nValue(10) {} void SetValue( int Value ) { _nValue = Value;} int GetValue() { return _nValue; } private : int _nValue; }; void main() { MyObject* MyObj1 = MyObject::GetSingleton(); cout << MyObj1->GetValue() << endl; // MyObj2는 Myobj1과 동일한 객체입니다. MyObject* MyObj2 = MyObject::GetSingleton(); MyObj2->SetValue(20); cout << MyObj1->GetValue() << endl; cout << MyObj2->GetValue() << endl; }
templateclass Stack { public: explicit Stack( int size ); ~Stack(); // 초기화 한다. void Clear(); // 스택에 저장된 개수 int Count(); // 저장된 데이터가 없는가? bool IsEmpty(); // 데이터를 담을 수 있는 최대 개수 int GetStackSize(); // 데이터를 저장한다. bool push( T data ); // 스택에서 빼낸다. T pop(); private: T* m_aData; int m_Count; int m_Size; }; template < typename T > Stack ::Stack( int size ) { m_Size = size; m_aData = new T[m_Size]; Clear(); } template < typename T > Stack ::~Stack() { delete[] m_aData; } template < typename T > void Stack ::Clear() { m_Count = 0; } template < typename T > int Stack ::Count() { return m_Count; } template < typename T > bool Stack ::IsEmpty() { return 0 == m_Count ? true : false; } template < typename T > int Stack ::GetStackSize() { return m_Size; } template < typename T > bool Stack ::push( T data ) { // 저장할 수 있는 개수를 넘는지 조사한다. if( m_Count >= m_Size ) { return false; } // 저장 후 개수를 하나 늘린다. m_aData[ m_Count ] = data; ++m_Count; return true; } template < typename T > T Stack ::pop() { // 저장된 것이 없다면 0을 반환한다. if( m_Count < 1 ) { return 0; } // 개수를 하나 감소 후 반환한다. --m_Count; return m_aData[ m_Count ]; }
template < typename T > export int Stack그러나 export라는 키워드를 사용하면 컴파일 에러가 발생합니다. 이유는 현재 대부분의 C++ 컴파일러에서는 export라는 키워드를 지원하지 않습니다. export를 아직 지원하지 못하는 이유는 이것을 지원하기 위해 필요로 하는 노력은 컴파일러를을 새로 만들 정도의 노력을 필요로 할 정도로 어렵다고 합니다. 현재까지도 대부분의 컴파일러 개발자들은 구현 계획을 세우지도 않고 있으며 일부에서는 구현에 반대하는 의견도 있다고 합니다.::GetStackSize() { return m_Size; }
// stack.h 파일 template이것으로 클래스 템플릿에 대한 설명은 다 한 것 같습니다. 함수 템플릿에 대한 글을 이미 보셨으면 템플릿에 대한 어느 정도 이해를 가지고 있을 테니 어렵지 않게 이해를 할 수 있으리라 생각합니다만 저의 부족한 글 때문에 어렵지 않았을까라는 걱정도 조금합니다.class Stack { public: // 초기화 한다. void Clear(); }; #include "stack.inl" // stack.inl 파일 template < typename T > void Stack ::Clear() { m_Count = 0; }
최신 콘텐츠