윤성우의 열헐 C++
윤성우의 열혈 c++) Chapter 14. 템플릿 (Template) 2
tose33
2022. 3. 26. 16:22
클래스 템플릿의 특수화
- 함수 템플릿의 특수화: 매개변수로 받는 특정 자료형에 따라 구분이 되는 다른 행동을 보이기 위해.
- 클래스 템플릿의 특수화: 생성되는 객체의 자료형에 따라 구분이 되는 다른 행동을 보이기 위해.
함수 템플릿과 마찬가지로 자료형에 대하여 특수화가 안되어있으면 컴파일러가 클래스 템플릿을 기반으로 해당 자료형의 템플릿 클래스를 생성한다.
특수화가 되어있다면 별도의 템플릿 클래스를 생성하지 않고 정의되어 있는 템플릿 클래스가 호출된다.
#include <iostream>
#include <cstring>
using namespace std;
template <typename T>
class Point
{
private:
T xpos, ypos;
public:
Point(T x = 0, T y = 0) : xpos(x), ypos(y) {}
void ShowPosition() const
{
cout << '[' << xpos << ", " << ypos << ']' << endl;
}
};
// 클래스 템플릿 SimpleDataWrapper
template <typename T>
class SimpleDataWrapper
{
private:
T mdata;
public:
SimpleDataWrapper(T data) : mdata(data) {}
void ShowDataInfo() { cout << "Data: " << mdata << endl; }
};
// 클래스 템플릿 SimpleDataWrapper를 char* 에 대하여 특수화
template<>
class SimpleDataWrapper<char*>
{
private:
char *mdata;
public:
SimpleDataWrapper(char *data)
{
mdata = new char[strlen(data)+1];
strcpy(mdata, data);
}
void ShowDataInfo()
{
cout << "String: " << mdata << endl;
cout << "Length: " << strlen(mdata) << endl;
}
~SimpleDataWrapper() { delete []mdata; }
};
// 클래스 템플릿 SimpleDataWrapper를 텤플릿 클래스인 Point<int>형에 대하여 특수화
template<>
class SimpleDataWrapper<Point<int>>
{
private:
Point<int> mdata;
public:
SimpleDataWrapper(int x, int y) : mdata(x, y) {}
void ShowDataInfo()
{
mdata.ShowPosition();
}
};
int main()
{
// int형은 특수화 없음.
// 이 문장이 컴파일 될때 클래스 템플릿인 SimpleDataWrapper 을 기반으로
// 템플릿 클래스인 SimpleDataWrapper<int>가 만들어짐.
SimpleDataWrapper<int> iwrap(170);
iwrap.ShowDataInfo(); cout << endl;
// char* 형에 대하여 특수화 되있으므로 별도의 템플릿 클래스 생성하지 않고 정의되어 있는
// 템플릿 클래스가 호출됨.
SimpleDataWrapper<char*> swrap("HELLO WORLD!");
swrap.ShowDataInfo(); cout << endl;
SimpleDataWrapper<Point<int>> poswrap(3, 30);
poswrap.ShowDataInfo();
}
언제 template<typename T>를 쓰고 언제 template<>를 쓰는가?
template <typename T>
class Simple
{
public:
T SimpleFunc(T num) {}
};
위 템플릿은 클래스 정의에 T가 등장하므로, template <typename T>의 선언을 통해 T가 무엇을 의미하는지 알려야한다.
// Simple 템플릿 클래스를 int형에 대하여 특수화
template<>
class Simple<int>
{
public:
int SimpleFunc(int num) {}
};
위 템플릿은 Simple 템플릿을 특수화한 것인데 정의에 T가 등장하지 않는다.
이 특수화된 템플릿에서 중요한것은 <int>형이다.
따라서 T가 무엇인지는 알리지 않아도되지만 이 클래스가 템플릿 관련 정의라는것을 알리기 위해 template<> 을 선언해야 한다.
템플릿과 static
c++에서 맴버변수의 static은 컴파일시 한번만 초기화되고 함수를 빠져나가도 소멸되지 않게한다.
컴파일시 컴파일러는 함수 템플릿을 기반으로 템플릿 함수들을 생성한다.
매개변수로 int가 들어오면 int형 템플릿 함수를, double이 들어오면 double형 템플릿 함수를 만들어낸다.
따라서 함수 템플릿 내에서 지역변수가 static 선언되면, static 지역변수도 템플릿 함수 별로 따로 존재하게 된다.
(같은 함수 템플릿을 기반으로 만들어졌어도 다른 함수다)