C/C++ - 템플릿

Claire·2024년 9월 2일

템플릿

정의

템플릿이란

함수나 클래스를 개별적으로 다시 작성하지 않아도 여러 자료형으로 사용할 수 있도록 만들어놓은 일종의 틀

템플릿에는 함수 템플릿(function template)과 클래스 템플릿(class template) 2가지가 있다.

필요성

템플릿을 사용하는 이유는 무엇일까? 지금까지 우리가 클래스를 작성하고 멤버함수를 메인 함수에서 호출 할 때 해당 함수들의 데이터 타입을 사전에 선언을 해두고, 타입에 맞춰서 함수를 사용하며 호출을 해왔다. 그런데 과연 앞으로 코딩을하면서 우리가 모든 코드를 사전에 알고 모든 타입을 사전에 정의할 수 있을까?

예를 들어 Id 생성을 한다고 하면 숫자, 문자, 특수문자 외에는 입력할 수 없게 만든다고 예상을 할 수 있다. 하지만 여러 타입이 번갈아가면 들어갈 수 있는 구조라고 했을 때, 사용자가 숫자타입을 넣을지, 문자 타입을 넣을지 그도 아니면 또 다른 타입을 넣을지는 알 수 없다.

이렇듯 어떠한 데이터 타입이 들어올 지 모르는 상황에서 기능만을 우선 구현해두고, 객체나 함수를 생성하는 시점의 데이터 타입을 적용해 기능을 사용하기 위해 '템플릿(template)'을 사용한다.

TypeScript의 generic과 동일한 기능

구문 구조

클래스 템플릿

  • 범용형을 다룰 수 있는 클래스의 정의를 의미(= 클래스의 일반화)
  • 클래스 템플리승ㄹ 정의하면 차입에 따라 클래스 생성 가능'
  • 클래스 템플릿은 무조건 템플릿 인수를 명시해주어야 하며, 템플릿만으로는 컴파일러가 읽을 수 없기에 동작하지 않는다.
  • 클래스 템플릿은 객체가 생성되는 시점에 동작
// 클래스 템플릿의 기본 문법
template <class T>
class CStack {
	public:
    	생성자() {}
        소명자() {}
        멤버 함수() {}
    private:
    	멤버 변수;
        멤버 변수;
}

와 같이 정의하면 CStack 클래스의 데이터 타입은 호출될 때 결정이 난다.

template <class T, int i> class CStack {
public:
	CStack(int nS) {
		sz = nS;
		p = new T[sz];
	}
	~CStack() {
		delete[] p;
	}

	void Push(T a) {
		*p++ = a;  // 여기서의 *p는 메모리 주소값이 향하는 메모리 자체를 가리키고 있음 (포인터 변수와는 다름)
	}
	T Pop() {
		return *(--p) = NULL;
	}

private:
	T* p;  // 여기의 p는 메모리 주소값을 담는 포인터 변수
	int sz;
};

void main() {
	CStack<char, 200> test2(10);

	CStack<int, 10> test(5); // 객체가 생성되기 전까지 클래스 템플릿에 대한 코드가 생성되지 않는다
	
	for (int i = 0; i < 5; i++) {
		test.Push(i + 10);
	}
	for (int i = 0; i < 5; i++) {
		cout << test.Pop() << endl;
	}
};

클래스 템플릿 특징
1. 클래스 템플릿은 상속하여 사용 가능
2. 클래스를 중첩하여 정의하는 중첩 클래스 템플릿이 존재한다.
(클래스 내부에서 정의된 템플릿 클래스를 중첩 클래스 템플릿이라고 한다)
3. 템플릿 인수의 디폴트값 설정 가능
4. 특정 타입에 대한 동작 정의 가능(클래스 템플릿 특수화)

함수 템플릿

  • 범용형을 다룰 수 있는 함수의 정의를 의미
  • 함수를 만들어 낼 때, 함수의 기능은 명확하지만 데이터 타입을 모호하게 둠으로써, 어떠한 타입이든 들어갈 수 있도록 해놓은 상태
  • 컴파일러는 전달된 타입을 검사하며 그에 해당하는 함수를 생성한다
template <class T> Max(T a, T b)
{ 
	return (a > b) ? a : b;
}
  • 함수 선두에 template 키워드는 이 함수를 템플릿 형태로 만들겠다고 선언한 것
Max('A', 'B'); -> char Max(char a, char b) 함수 생성

즉, 컴파일 과정에서 함수가 생성된다.

다른 타입을 2개 이상 갖는 함수 템플릿

  • class T 타입이 한개 더 늘어난다
  • 함수의 정의 형태
template<class T1, T2> void pirnt(T1 a, T2 b)
{ 
	cout << a << "," << b << endl;
}

print('K', 10);  //문자열과 숫자형 타입
pritn(2, 2.4);  // 정수형과 실수형 타입

와 같이 꼭 동일한 타입의 인자가 들어가지 않아도 사용이 가능하다.

profile
SEO 최적화 마크업 개발자입니다.

0개의 댓글