'C++ Templates'에 해당되는 글 2건

  1. 2010.08.31 Advantages of Templates [C++]
  2. 2010.05.09 Templates

[C++] 템플릿의 이점

 

 템플릿은 다음의 경우 사용한다:

  • 어떤 자료형이든 연산이 가능한 typesafe collection class를 만들 때(ex: stack)
  • void형 포인터를 가질 수 있는 함수의 형 검사를 추가할 때
  • 스마트 포인터와 같이 타입에 따른 동작을 수정하는 연산자 중복 그룹 캡슐화를 할 때

 

 대부분의 이런 사용은 템플릿 없이 효력을 발휘할 수 있기는 하다; 그러나, 템플릿은 몇 가지 장점을 제공한다.

  • 템플릿은 작성하기 쉽다. 일일이 특성을 생성하는 대신 클래스나 함수의 일반적인 버전 하나만 만들면 된다.
  • 템플릿은 더 이해하기 쉬워지므로, 추상 타입 정보의 방식을 올바로 제공할 수 있다.
  • 템플릿은 typesafe하다. 왜냐하면 템플릿의 동작에 따른 타입이 컴파일 타임에 결정되어 컴파일러가 에러 발생 전에 타입을 검사하여 반응할 수 있기 때문이다.

 

더 많은 정보를 위해서 아래의 내용들을 보자. 

  • Templates and Macros
  • Templates and Void Pointers
  • Templates and Smart Pointers
  • Templates and Collection Classes


Templates and Macros
(템플릿과 매크로)


다수의 경우, 템플릿은 자료형을 결정짓는 템플릿화 변수(templated variable)를 대체하는 매크로 전처리기(preprocessor macros)처럼 동작한다. 하지만 매크로와:

define min(i, j) (((i) < (j)) ? (i) : (j))

템플릿:

template<class T> T min (T i, T j) { return ((i < j) ? i : j) }

에는 많은 차이가 있다.

 
매크로에는 다음과 같은 문제점이 있다:

  • 매크로 매개변수(macro parameter)가 겸용 자료형으로 되어있으면 컴파일러가 식별할 방법이 없다. 매크로는 어떤 특별한 타입 검사도 없이 확장된다.
  • i, j 매개변수는 두 번 비교된다. 예를 들어, 만약 두 매개변수가 둘 다 후위증가 변수를 가지고 있으면 증가 연산(incerement)은 두 번 작동할 것이다.
  • 매크로는 전처리기에 의해 확장되기 때문에, 컴파일러 에러 메시지는 매크로 정의 자체가 아니라 확장된 매크로를 참조할 것이다. 물론, 매크로는 디버깅 중에 확장된 형태로 나타날 것이다.

 

Templates and Void Pointers (템플릿과 void 포인터)

 

void 포인터와 함께 사용되고 있는 많은 함수들은 템플릿으로도 사용 가능하다. void 포인터는 알 수 없는 타입의 데이터를 연산하는 함수를 허용하기 위해 종종 사용된다. void 포인터를 사용 할 때, 컴파일러는 타입을 구별할 수 없어서 타입-특성(type-specific) 연산자 사용, 연산자 오버로딩, 생성자 또는 소멸자와 같은 타입 검사나 타입-특성 동작을 할 수 없게 된다.

 

템플릿을 사용하면, 타입이 결정된 자료를 연산할 수 있는 함수나 클래스를 만들 수 있다. 타입은 템플릿 정의에서 추상화된 것으로 보이지만, 컴파일 타임에 컴파일러는 각 타입 특성에 맞는 함수의 버전을 각기 따로 생성한다. 이것은 컴파일러가 타입 특성에 따라 동작하려고 하는 클래스나 함수를 다룰 수 있도록 한다. 또한 구조체처럼 복잡한 여러 타입들에 대해 특별한 경우를 만들 필요가 없게 해 주기 대문에 템플릿은 코드의 명확성(clarity)도 향상시킨다.

 

Templates and Smart Pointers (템플릿과 스마트 포인터)

 

 C++는 포인터를 캡슐화하고 연산 포인터에 기능을 추가하는 포인터 오버라이드된 스마트 포인터 클래스 생성을 허용한다. 템플릿은 거의 대부분의 타입을 가리키는 포인터를 캡슐화하는 일반적인 래퍼(wrapper) 생성을 허용한다.

 

다음의 코드는 간단한 쓰레기 수집기(garbage collector) 참조 횟수를 보여준다. Ptr<T> 템플릿 클래스는 RefCount로부터 파생된 어떠한 클래스에서도 쓰레기 수집기 포인터를 사용할 수 있게 한다.

 

Example

// templates_and_smart_pointers.cpp
#include <stdio.h>

#define TRACE printf

class RefCount {
   int crefs;
public:
   RefCount(void) {
      crefs = 0;
   }

   ~RefCount() {
      TRACE("goodbye(%d)\n", crefs);
   }

   void upcount(void) {
      ++crefs;
      TRACE("up to %d\n", crefs);
   }

   void downcount(void)
   {
      if (--crefs == 0)
         delete this;
   else
      TRACE("downto %d\n", crefs);
   }
};


class Sample : public RefCount {
public:
   void doSomething(void) {
      TRACE("Did something\n");
   }
};


template <class T> class Ptr {
   T* p;
public:
   Ptr(T* p_) : p(p_) {
      p->upcount();
   }

   ~Ptr(void) {
      p->downcount();
   }

   operator T*(void) {
      return p;
   }

   T& operator*(void) {
      return *p;
   }

   T* operator->(void) {
      return p;
   }

   Ptr& operator=(Ptr<T> &p_) {
      return operator=((T *) p_);
   }

   Ptr& operator=(T* p_) {
      p_->upcount();
      p->downcount();
      p = p_;
      return *this;
   }

   Ptr(const Ptr<T> &p_) {
      p = p_.p;
      p->upcount();
   };
};


int main() {
   Ptr<Sample> p  = new Sample; // sample #1
   Ptr<Sample> p2 = new Sample; // sample #2
   p = p2; // #1 will have 0 crefs, so it is destroyed;
         // #2 will have 2 crefs.
   p->doSomething();
   return 0;
   // As p2 and p go out of scope, their destructors call
   // downcount. The cref variable of #2 goes to 0, so #2 is
   // destroyed
}


 

Output

up to 1
up to 1
up to 2
goodbye(0)
Did something
downto 1
goodbye(0)


 

 

 RefCountPtr<T> 클래스는 둘 다 RefCount 로부터 상속한 인스턴스 부담(instance overhead)마다 int에 영향을 주는 어떤 클래스든지 간단한 쓰레기 수집 솔루션을 제공한다. Ptr처럼 일반적인 클래스 대신에 Ptr<T>같은 매개변수를 가지는 클래스 사용의 주요한 이득은 완벽히 typesafe 하다는 것이다. 앞의 코드는 Ptr<T>가 거의 어떤 곳에서도 T*로 사용되는 것을 보장한다. 반면에, 일반적인 Ptr은 단순히 void*형으로 암묵적인(implicit) 변환만 제공할 것이다.

 

클래스가 쓰레기 수집된 파일, 심볼(symbols), 문자열(strings) 등을 생성하고 조작하는 것을 고려해보아라. Ptr<T> 클래스 템플릿으로부터 컴파일러는 Ptr<File>, Ptr<Symbol>, Ptr<String> 등의 템플릿 클래스들을 만들 것이다. 그 클래스들의 멤버 함수로는 Ptr<File>::~Ptr(), Ptr<File>::operator File*(), ptr<String>::~Ptr(), Ptr<String>::operator String*() 등이 있을 것이다.

 

Templates and Collection Classes (템플릿과 콜렉션 클래스)

 

템플릿은 콜렉션 클래스를 도구로 삼기에 좋은 방법이다.

// templates_and_collection_classes.cpp
template <class T, int i> class MyStack
{
   T StackBuffer[i];
   int cItems;
public:
   MyStack( void ) : cItems( i )
   {
   };
   void push( const T item );
   T pop( void );
};

template <class T, int i> void MyStack< T, i >::push( const T item )
{
   if( cItems > 0 )
      StackBuffer[--cItems] = item;
   else
      throw "Stack overflow error.";
}

template <class T, int i> T MyStack< T, i >::pop( void )
{
   if( cItems < i )
      return StackBuffer[cItems++]
   else
      throw "Stack underflow error.";
}

int main()
{
   MyStack<char , 1> v;
   v.push('a');
}

Comments

MyStack 콜렉션은 스택의 간단한 구현(implementation)이다. T와 i 두 템플릿 매개변수는 스택에서 원소의 자료형과 최대 항목 갯수를 조건으로 지정한다. push와 pop 멤버 함수는 스택에 바닥에서부터 차오르도록 스택 상에서 항목을 넣거나 뺀다.

'Programming Languages > C++ Templates' 카테고리의 다른 글

Template Specifications  (0) 2010.05.10
Templates Overview  (0) 2010.05.10
Templates  (0) 2010.05.09
Posted by 독뽀
,

역시나 이번에도 번역겸 요약이다.

Microsoft Visual Studio 2010 Help Libarary를 참고하여 작성됨을 미리 밝혀둡니다.
저작권 등 문제가 된다면 꼭 메일 주세요!! 바로 삭제나 블라인드 조치 취하겠습니다. asgawa@gmail.com

Templates(이하 템플릿)

C++ 템플릿은 함수나 클래스의 구성을 정의할 수 있게 하며, 이는 유동적인 자료형(런타임 중 어느것이 결정될지 모르는)을 가진 함수나 클래스가 연산을 할 수 있게 한다. C++ 템플릿을 사용하는 Microsoft 도구는 ISO/ANSI C++ 기준을 따르고 있다.

자료형만 다르고 동일한 코드의 통합이 목표인 상황에서 템플릿을 사용하라.

1. 같은 알고리즘을 적용할 함수이고, 자료형만 다르게 적용하기를 요구하는 함수를 만들 때
2. typesafe class(자료형에 관해 안전한 클래스) 집합을 개발할 때

템플릿은 때때로 C 언어의 매크로와 void형 포인터보다 더 좋은 해결책이 되기도 하며, collections(MFC에서 템플릿이 사용되는 main중 하나)나 스마트 포인터로 작업을 할 때 특히 유용하다.



앞으로 추가될 내용들

Overview
   Provides general information about templates, or parameterized types, in Visual C++.
Specifications
   Provides a specification for a template declaration.
Advantages of Templates
   Describes advantages of C++ templates. 
typename
   Describes the typename keyword.
Referencing Templates [C++ Language]
   Provides a task showing how to reference templates in your code.
Angle Bracket Placement
   Describes how angle brackets are placed in templates.
Differences from Other Implementations
   Discusses Microsoft-specific implementations of templates.
Name Resolution
   Discusses the three types of names in template definitions.
Class Templates
   Describes how to use and work with class templates.
Function Templates
   Describes how to use and work with function templates.

 

'Programming Languages > C++ Templates' 카테고리의 다른 글

Advantages of Templates [C++]  (0) 2010.08.31
Template Specifications  (0) 2010.05.10
Templates Overview  (0) 2010.05.10
Posted by 독뽀
,