13. C++ 코드 재활용(4) - 클래스 템플릿(스택)

WanJu Kim·2022년 12월 16일
0

C++

목록 보기
58/81

코드를 재활용하는 다음 방법으로는 템플릿을 이용하는 방법이 있다. 예전에 Stack 클래스를 만들어본 적이 있다. 그 클래스는 데이터형으로 unsinged long을 가졌다. 데이터형을 double이나 string으로 바꿀 수도 있었을 것이다. 물론 그때 데이터형 이외의 코드는 변하지 않을 것이다. 그러니 만약 다른 데이터형의 코드가 필요하다면, 클래스를 새로 작성하는 게 아니라, 임의의 데이터형이 감당 가능하도록 작성하는 게 코드를 재활용하는 방법이다. 다음은 이전에 작성한 Stack 클래스다.

typedef unsigned long Item;
class Stack
{
private:
	enum {MAX  = 10};
	Item items[MAX];
	int top;
public:
	Stack();
	bool IsEmpty() const;
	bool IsFull() const;
	bool Push(const Item& item);
	bool Pop(Item& item);
};

이 Stack 정의를 템플릿 정의로, Stack 멤버 함수를 템플릿 멤버 함수로 바꾸겠다. 템플릿 함수처럼 다음과 같은 코드를 쓴다.

template <class Type>
or
template <typename Type>

함수처럼 저 구문 바로 밑에다가 클래스 정의를 하면 된다. 여기서 Type과 같은 포괄적인 데이터형 식별자를 '데이터형 매개 변수'라 한다. 일반적으로 Type이나, T 명칭을 많이 쓰고, 저 문구 대신에 데이터형이 들어간다. 꼭 자료형이 아니라 실제로 쓰일 포괄적인 데이터가 들어간다. ex) 기본 데이터형, 클래스, 구조체 등. 클래스 메서드 머리도 비슷하게 한다.

// 템플릿 전
bool Stack::Push(const Item & item)
{
	...
}

// 템플릿 후
template <class Type> // or template <typename Type>
bool Stack<Type>::Push(const Type & item)
{
	...
}

클래스 선언 안에서 정의된 메서드(인라인 함수)는 템플릿 제한자와 클래스 제한자를 생략 할 수 있다.

#pragma once
template <class Type>
class Stack
{
private:
	enum {MAX  = 10};
	Type items[MAX];
	int top;
public:
	Stack();
	bool IsEmpty() const;
	bool IsFull() const;
	bool Push(const Type& item);
	bool Pop(Type& item);
};

template<class Type>
inline Stack<Type>::Stack()
{
	top = 0;
}

template<class Type>
inline bool Stack<Type>::IsEmpty() const
{
	return top == 0;
}

template<class Type>
inline bool Stack<Type>::IsFull() const
{
	return top == MAX
}

template<class Type>
inline bool Stack<Type>::Push(const Type& item)
{
	if (top < MAX)
	{
		items[top++] = item;
		return true;
	}
	else
		return false;
}

template<class Type>
inline bool Stack<Type>::Pop(Type& item)
{
	if (top > 0)
	{
		item = items[--top];
		return true;
	}
	else
		return false;
}

이 템플릿들이 클래스와 멤버 함수 정의가 아님을 깨닫는 게 중요하다. 단지 클래스와 멤버 함수 정의를 생성하는 방법을 컴파일러에게 알려주는 지시문이다. 그래서 클래스 템플릿과 멤버 함수 템플릿이 한 파일에 쓰인다. 그리고 이걸 실행해서 type이 정해지면 구체화 or 특수화라고 부른다.

Stack<int> kernels;		// int 값들의 스택 생성.
Stack<string> colonels;	// string 객체들의 스택 생성.

이 두 선언을 컴파일러가 발견하면, Stack<Type> 템플릿을 사용하여 두 개의 서로 다른 클래스와, 클래스 메서드들의 집합을 생성할 것이다.

두 개 이상의 매개 변수도 사용할 수 있다.

template <class T1, class T2, ...>

또한 함수처럼 디폴트 값을 넣을 수도 있다.

template <class T1, class T2 = int>
class Topo...

Topo<double, double> m1;	// M1, M2 둘 다 double형.
Topo<double> m2;			// T1은 double형, T2는 int형.

너무 사사로운 것이 많아서 다음에 쓸 일 있을 때 해야겠다;

profile
Question, Think, Select

0개의 댓글