반응형
[문과 코린이의 IT 기록장] C++ - 클래스 템플릿의 특수화(Class Template Specialization)
(클래스 템플릿 특수화, 클래스 템플릿의 부분 특수화)
[ 클래스 템플릿에 대한 이전 포스팅 ]
1. 클래스 템플릿 특수화
- 함수 템플릿을 특수화하는 이유 : 특정 자료형에 대해, 구분이 되는 다른 행동을 보이기 위해서
- 클래스 템플릿을 특수화하는 이유 : 특정 자료형을 기반으로 생성된 객체에 대해, 구분이 되는 다른 행동양식을 적용하기 위해서
* 즉 클래스 템플릿을 특수화하면, 템플릿을 구성하는 맴버함수의 일부 또는 전부를 다르게 행동하도록 정의할 수 있음
ex 1 ) 클래스 템플릿
template <typename T>
class SoSimple
{
public:
T SimpleFunc(T num) { ... }
}
ex 2 ) int형에 대해 특수화된 템플릿 클래스
template<>
class SoSimple<int>
{
public:
int SimpleFunc(int num){ ... }
}
이와 같이 int형에 대해 특수화가 된 이후 아래와 같이 객체생성을 할 경우, 객체가 생성된다.
SoSimple<int> obj;
Case 1 )
#include <iostream>
using namespace std;
/* 클래스 템플릿 Point 정의 */
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(const 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>형에 대해 특수화함.
// 목적 : 자료형의 이름만 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() {
SimpleDataWrapper<int> iwrap(170);
iwrap.ShowDataInfo();
// char*형에 대해서 특수화가 진행되었으므로, 별도의 템플릿 클래스가 생성되지 않고, 32행에 정의된 탬플릿 클레스의 객체가 생성된다.
SimpleDataWrapper<char*> swrap("Class Template Specialization");
swrap.ShowDataInfo();
// Point<int>형에 대해서 특수화가 진행되었으므로, 별도의 템플릿 클래스가 생성되지 않고, 51행에 정의된 탬플릿 클레스의 객체가 생성된다.
SimpleDataWrapper<Point<int>> poswrap(3, 7);
poswrap.ShowDataInfo();
return 0;
}
2. 클래스 템플릿의 부분 특수화
Case 2 )
#include<iostream>
using namespace std;
template <typename T1, typename T2>
class MySimple {
public:
void WhoAreYou() {
cout << "size of T1 : " << sizeof(T1) << endl;
cout << "size of T2 : " << sizeof(T2) << endl;
cout << "<typename T1, typename T2>" << endl;
}
};
template<>
class MySimple<int, double> {
public:
void WhoAreYou(){
cout << "size of int : " << sizeof(int) << endl;
cout << "size of double : " << sizeof(double) << endl;
cout << "<int, double>" << endl;
}
};
/*
template <typename T1>
class MySimple<T1, double> // T2를 double로 부분 특수화
{
public:
void WhoAreYou(){
cout << "size of T1 : " << sizeof(T1) << endl;
cout << "size of double : " << sizeof(double) << endl;
cout << "<T1,double>" << endl;
}
};
*/
int main() {
MySimple<char, double>obj1; // 주석이 해제되면 <T1,double> 특수화 부분이 실행됨
obj1.WhoAreYou();
MySimple<int, long> obj2;
obj2.WhoAreYou();
MySimple<int, double> obj3; // 부분 특수화에 해당되더라도, 전체 특수화가 우선적으로 실행됨
obj3.WhoAreYou();
return 0;
}
* 유의사항 - 아직 공부하고 있는 문과생 코린이가, 정리해서 남겨놓은 정리 및 필기노트입니다. - 정확하지 않거나, 틀린 점이 있을 수 있으니, 유의해서 봐주시면 감사하겠습니다. - 혹시 잘못된 점을 발견하셨다면, 댓글로 친절하게 남겨주시면 감사하겠습니다 :) |
반응형