같은 내용을 담고있는(기능을 수행하는) 함수라고 해도 반환형, 매개변수형(입력 인자형)에 따라 다른 함수가 될 수 있다. 마찬가지 클래스도 멤버 내 변수, 함수 형에 따라 같은이름의 다른 클래스가 될 수 있다. 이 때 같은기능을 하는 함수 및 클래스를 한번만 정의하되 서로 다른 형(type)을 입력, 반환(클래스 정의, 멤버 변수, 함수 정의 시 반환형, 매개변수형, 인자형...etc) 하고자 할 때 템플릿을 사용한다.
#include <iostream>
using namespace std;
// 템플릿 인자인 T1, T2. 두 개의 형변수(type variables)를 둘 수 있고 디폴트값 또한 지정 가능
template <typename T1, typename T2=void> // T2의 디폴트값은 void 이다.
T2 Swap(T1 param1, T1 param2)
{
T1 param3 = param1;
param1 = param2;
param2 = param3;
}
int main()
{
int num1=5, num2=6;
Swap<int>(num1, num2);
// 함수 템플릿을 호출하면 컴파일러에 인식된 형에(typename) 맞는 템플릿 함수를 임시생성한다.
/* 함수 호출시와 마찬가지로 좌측 매개변수부터 복사가 된다. 따라서 T1=int로 초기화 되고 T2는
디폴트값인 void로 초기화 된다. 이때 컴파일러는 입력 인자인 num1, num2의 형이 int임에 T1이
int임을 미루어 짐작할 수 있다. <int>를 생략할 수 있다는 말!!
*/
cout << "num1 = " << num1 << "\nnum2 = " << num2 << endl;
// Swap 함수 정상작동(excution) 확인
}
자세한 설명은 주석 참조
template <typename T>
class Point
{
T xpos, ypos;
public:
Point(T x, T y)
void Show()
{
cout << xpos << ypos << endl;
}
};
int main()
{
// 이 역시나 클래스 템플릿 호출 시 **임시 템플릿 클래스를 생성하여 객체를 생성한다.**
Point <int> pos1(3,5);
Point <char> pos2 = {'a', 'b'};
Point <double> pos3 = {0.05, 0.01};
// 클래스에선 '<>' 부분을 생략할 수 없다. 반드시 명시해야 함
return 0;
}
배열클래스는 정의 시 반환형에 따라(변수원형인지, 포인터형인지, 더블포인터형인지) 여러개의 함수를 생성해야 했는데 이번기회에 템플릿을 통해 이를 하나로 통합하여 보자.
#include "Point.h" // Point class 참조
#include <iostream>
using namespace std;
typedef Point * POINT_PTR // Point클래스의 포인터형 이름을 POINT_PTR로 정의(typedef)
template <class T>
class arrayclass
{
T * arr;
int arrlen;
// 배열의 고유성을 위해 복사생성자, 대입연산자에는 private 접근성을 부여한다.
arrayclass(arrayclass & acopy);
arrayclass & operator=(arrayclass & acopy);
public:
arrayclass(int len=0):arrlen(len)
{
arr = new T[len]
}
T & operator[](int idx)
{
if(idx <0 || idx >= arrlen)
{
cout << "out of range" << endl;
exit(1);
}
return arr[idx];
}
// 기타 함수 생략...
};
이에 대한 실전문제 적용은 Bank account ver.6에서 다뤄보자.
template <typename T>
/* 선언부의 클래스템플릿과 동일한 선언문자, 문자 사용.
단, 아래 함수정의에서 **미지변수 T가 필요한 경우에만** 해당하며 T가 필요 없을 시
template<> 로 써준다.
*/
type classname<T>::functionname(factor1, factor2, ...)
의 방식대로 함수를 정의하여야 한다.
#include "arrayclass.h"
#include "arrayclass.cpp"
// 이하 헤더파일 중략...
int main()
{
arrayclass <Point> arc1;
// 이처럼 **템플릿클래스**를 생성하고자 한다면 분리된 소스파일도 참조해야 한다.
arrayclass <POINT_PTR> arc2;
// ..생략...
}
함수 템플릿 - 템플릿 함수 / 클래스 템플릿 - 템플릿 클래스의 1. 사용법 2. 사용 경우 3. 규칙 에 관하여 알게 되었다. bank account 프로젝트에 적용해 보자.