GSI

단위 전략과 단위 전략 클래스..

예로 들 것은 객체를 생성할때 template를 통해서 new와 malloc를 선택적으로 해주기 위함입니다.
다른 방법들도 몇가지 덧 붙여서 설명하겠습니다.

단위 전략의 설명은 책에 잘 나와 있으니 패스 ^^

우선 단위 전략에 필요한 인터페이스 즉, new, malloc로 구현된 두개의 struct 문입니다.

template < class T >
struct OpNewCreator
{
   static T* Create()
   { return new T }
};

template < class T >
struct MallocCreator
{
   static T* Crate()
   {
      void* buf = std::malloc(sizeof(T));
      if(!buf) return 0;
      return new(buf) T;
   }
};

두개의 단위 전략을 생성 했다면 아래의 단위 전략을 사용할 클래스를 하나 제작 합니다.

template < class CreationPolicy >
class WidgetManager : public CreationPolicy
{
public:
   WidgetManager()
   {
      CTest* p = CreationPolicy().Create();
      ...
   }
   ...
};

어때요?.. 멋지지 않나요?..  CreationPolicy 에 들어 오는 타입에 따른 Create() 를 호출하게 되는 구조입니다.
사용할때는 아래와 같이 적용이 가능해 집니다.

typedef WidgetManager< OpNewCreator<CTest> > MyWidgetMgr;
MyWidgetMgr a;

즉, OpNewCreatorMallocCreator 로 바꾸면 다른 기능을 할 수 있다는 거죠.
이게 바로 단위 전략이라는 거 같네요..

이것을 조금더 자연스럽게 해주는 기능이 또 있습니다.
바로 템플릿 템플릿 인자를 통해서요.
이 설명은 좀더 정리 되면 적도록 하구요..

다른 내용을 주제로 더 적도록 하겠습니다.

위의 단위 전략의 Create() 함수에 다른 인자를 더 넣는건 어떻게 할까.. 고민을 해봤어요.
즉 template 의 인자를 하나더 주자는 예기죠.

아래와 같이 바꾸어 보겠습니다.

template < class T, class U >
struct OpNewCreator
{
   static T* Create( U* u )
   {
      ...
   }
};

이렇게 말이죠. U 의 타입을 받아서 T를 생성한다.
이때는 아래와 같이 타입을 하나더 넣어 주어야 합니다.

typedef WidgetManager< OpNewCreator<CTest, CTest2> > MyWidgetMgr;

이렇게 해서 두개의 타입을 연결하였습니다.
근데 이때, U 에 들어 가는 타입을 디폴트 타입으로 지정하면 어떨까 생각 했죠.

template < class T, class U = CTest2 >
...

이렇게 하면 뒤어 인자를 적어줄 필요가 없게 됩니다.

typedef WidgetManager< OpNewCreator<CTest> > MyWidgetMgr;

바로 이렇게 말이죠.

그렇다면 Create( U* u ) 의 U 인자를 특정 타입으로 특화 하면 어떨까 생각 했죠.

template < class T, class U = CTest2 >
struct OpNewCreator
{
   static T* Create( CTest2* u )
   {
      ...
   }
};

이렇게 하게 되면 WidgetManager 내부에서 제한적인 코딩이 가능해 집니다.
즉, CTest2 의 인자만을 Create()에 집어 넣지 않으면 컴파일 에러가 발생하게 되죠.
다른 인자를 집어 넣는 실수를 막을 수 있을거 같네요.

CTest* p2 = new CTest();
CTest* p = CreationPolicy().Create( p2 );

이렇게 하면 p2가 CTest2가 아니기 때문에 에러가 나게 됩니다. ^^

Tip.
template 를 사용하게 되면 프로그램의 실수를 컴파일 타임에 잡아 주기 위한 기능으로도
적용이 되고 있습니다. 여러사람이 작업을 하거나 제한적인 코딩을 통한 에러를 막기 위한 방법으로
괜찮은 기능인거 같아요.

이상..

잘못된 내용이나 궁금증은 언제든 환영합니다. ^^
Posted by gsi
: