CS/C++

[Mastering C++ Programming] - Explicit class specializations

sliver__ 2022. 12. 6. 23:12
728x90
  • 다른 데이터 유형과 관련하여 특정 데이터 유형을 특별하게 처리해야 하는 경우가 있습니다.
  • 이러한 경우 C++는 차등 처리를 통해 선택적 데이터 유형을 처리하기 위해 명시적인 클래스 특수화 지원을 제공합니다.

 

  • STL deque 컨테이너를 사용하는 경우 deque는 문자열, int, double 및 long과 같이 저장하기에 괜찮아 보이지만 deque를 사용하여 많은 bool을 저장하기로 결정한 경우 bool 데이터 유형은 최소 1바이트를 사용하지만 컴파일러마다 다를 수 있습니다. 
  • 단일 비트는 참 또는 거짓을 효율적으로 나타낼 수 있지만 부울은 최소한 1바이트, 즉 8비트를 차지하고 나머지 7비트는 사용되지 않습니다.
  • 매우 큰 boo deque를 저장해야 하는 경우 확실히 효율적인 아이디어가 아닌 것 같습니다. 그러므로 bool에 대해 다른 특수 클래스 또는 템플릿 클래스를 작성할 수 있습니다.
  • explicit template specializations은 전체 템플릿 특수화라고도 합니다.
  • 코드 예제는 아래와 같습니다.
//dynamicarray.h

#include <iostream>
#include <deque>
#include <algorithm>
#include <iterator>
using namespace std;

template < class T >
class DynamicArray {
      private:
           deque< T > dynamicArray;
           typename deque< T >::iterator pos;

      public:
           DynamicArray() { initialize(); }
           ~DynamicArray() { }

           void initialize() {
                 pos = dynamicArray.begin();
           }

           void appendValue( T element ) {
                 dynamicArray.push_back ( element );
           }

           bool hasNextValue() { 
                 return ( pos != dynamicArray.end() );
           }

           T getValue() {
                 return *pos++;
           }
 
};
  • 템플릿 클래스 특수화의 구문은 템플릿 <> 클래스 DynamicArray<bool> { };입니다. 
  • 클래스 템플릿 표현식은 비어 있으며 모든 데이터 유형에 작동하는 클래스 템플릿의 이름과 bool 데이터 유형에 작동하는 클래스 이름은 템플릿 표현식 <bool>과 동일하게 유지됩니다.
  • 자세히 관찰하면 bool용 특수 DynamicArray 클래스는 내부적으로 deque< bitset<8> >, 즉 8비트 비트 집합의 deque를 사용하며, 필요한 경우 deque는 자동으로 더 많은 bitset<8> 비트를 할당합니다.
  • bitset 변수는 true 또는 false를 나타내는 데 1비트만 사용하는 메모리 효율적인 STL 컨테이너입니다.
// "dynamicarrayforbool.h"
#include <iostream>
#include <bitset>
#include <algorithm>
#include <iterator>
using namespace std;

template <>
class DynamicArray<bool> {
      private:
          deque< bitset<8> *> dynamicArray;
          bitset<8> oneByte;
          typename deque<bitset<8> * >::iterator pos;
          int bitSetIndex;

          int getDequeIndex () {
              return (bitSetIndex) ? (bitSetIndex/8) : 0;
          }
      public:
          DynamicArray() {
              bitSetIndex = 0;
              initialize();
          }

         ~DynamicArray() { }

         void initialize() {
              pos = dynamicArray.begin();
              bitSetIndex = 0;
         }

         void appendValue( bool value) {
              int dequeIndex = getDequeIndex();
              bitset<8> *pBit = NULL;

              if ( ( dynamicArray.size() == 0 ) || ( dequeIndex >= ( dynamicArray.size()) ) ) {
                   pBit = new bitset<8>();
                   pBit->reset();
                   dynamicArray.push_back ( pBit );
              }

              if ( !dynamicArray.empty() )
                   pBit = dynamicArray.at( dequeIndex );
         
              pBit->set( bitSetIndex % 8, value );
              ++bitSetIndex;
         }

         bool hasNextValue() {
              return (bitSetIndex < (( dynamicArray.size() * 8 ) ));
         }

         bool getValue() {
              int dequeIndex = getDequeIndex();
 
              bitset<8> *pBit = dynamicArray.at(dequeIndex);
              int index = bitSetIndex % 8;
              ++bitSetIndex;

              return (*pBit)[index] ? true : false;
         }
};
//main.cpp
#include "dynamicarray.h"
#include "dynamicarrayforbool.h"

int main () {
    
    DynamicArray<int> intArray;

    intArray.appendValue( 100 );
    intArray.appendValue( 200 );
    intArray.appendValue( 300 );
    intArray.appendValue( 400 );

    intArray.initialize();

    cout << "\nInt DynamicArray values are ..." << endl;
    while ( intArray.hasNextValue() )
          cout << intArray.getValue() << "\t";
    cout << endl;

    DynamicArray<char> charArray;
    charArray.appendValue( 'H' );
    charArray.appendValue( 'e' );
    charArray.appendValue( 'l' );
    charArray.appendValue( 'l' );
    charArray.appendValue( 'o' );

    charArray.initialize();

    cout << "\nChar DynamicArray values are ..." << endl;
    while ( charArray.hasNextValue() )
          cout << charArray.getValue() << "\t";
    cout << endl;

    DynamicArray<bool> boolArray;
    
    boolArray.appendValue ( true );
    boolArray.appendValue ( false );
    boolArray.appendValue ( true );
    boolArray.appendValue ( false );

    boolArray.initialize();

    cout << "\nBool DynamicArray values are ..." << endl;
    while ( boolArray.hasNextValue() )
         cout << boolArray.getValue() << "\t";
    cout << endl;

    return 0;

}

 

  • 결과는 아래와 같습니다.
Int DynamicArray values are ...
100     200     300     400

Char DynamicArray values are ...
H       e       l       l       o

Bool DynamicArray values are ...
1       0       1       0       0       0       0       0
728x90