Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

SYDev

C++ Chapter 14-2 : 클래스 템플릿의 특수화(Class Template Specialization) 본문

Programming Lang/C++

C++ Chapter 14-2 : 클래스 템플릿의 특수화(Class Template Specialization)

시데브 2023. 7. 31. 16:35

클래스 템플릿 특수화

  • 함수 템플릿을 특수화 하듯이 클래스 템플릿도 특수화를 할 수 있다.
  • 클래스 템플릿을 특수화하는 이유는 특정 자료형을 기반으로 생성된 객체에 대해, 구분이 되는 다른 행동양식을 적용하기 위해서이다.

 관련하여 예제를 살펴보자.

#include <iostream>
#include <cstring>
using namespace std;

template <class 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;
    }
};

template <class T>
class SimpleDataWrapper
{
private:
    T mdata;
public:
    SimpleDataWrapper(T data) : mdata(data)
    { }
    void ShowDataInfo(void)
    {
        cout<<"Data: "<<mdata<<endl;
    }    
};

template<>
class SimpleDataWrapper <char*>	//클래스 SimpleDataWrapper를 char*형에 대하여 특수화 
{
private:
    char* mdata;
public:
    SimpleDataWrapper(char* data) 
    { 
        mdata = new char[strlen(data)+1];
        strcpy(mdata, data);        
    }
    void ShowDataInfo(void)
    {
        cout<<"Data: "<<mdata<<endl;
        cout<<"Length: "<<strlen(mdata)<<endl;
    }     
    ~SimpleDataWrapper()
    {
        delete []mdata;
    }
};

template<>
class SimpleDataWrapper <Point<int>>	//클래스 SimpleDataWrapper를 Point<int>형에 대하여 특수화
{
private:
    Point<int> mdata;
public:
    SimpleDataWrapper(int x, int y) : mdata(x, y)
    { }
    void ShowDataInfo(void)
    {
        mdata.ShowPosition();
    }
};

int main(void)
{
    SimpleDataWrapper<int> iwrap(170);	//특수화가 진행되지 않은 자료형이므로 템플릿 클래스 SimpleDataWrapper<int> 생성
    iwrap.ShowDataInfo();
    SimpleDataWrapper<char*> swrap("Class Template Specialization");	//특수화가 이미 진행되었으므로 템플릿 클래스 새로 생성 X
    swrap.ShowDataInfo();
    SimpleDataWrapper<Point<int>> poswrap(3, 7);	//특수화가 이미 진행되었으므로 템플릿 클래스 새로 생성 X
    poswrap.ShowDataInfo();

    return 0;
}
Data: 170
Data: Class Template Specialization
Length: 29
[3, 7]

 

클래스 템플릿의 부분 특수화

 다음과 같은 형태로 클래스 템플릿의 부분 특수화를 진행할 수 있다.

template <class T1, class T2>
class MySimple { . . . . }

template <>
class MySimple<char, int> { . . . . }	//자료형의 수가 늘어난 클래스 템플릿의 특수화

template <class T1, class T2>
class MySimple<T1, int> { . . . . }	//클래스 템플릿의 부분 특수화

 이와 관련된 예제를 살펴보자.

#include <iostream>
using namespace std;

template <class T1, class T2>
class MySimple
{
public:
    void WhoAreYou()
    {
        cout<<"size of T1: "<<sizeof(T1)<<endl;
        cout<<"size of T2: "<<sizeof(T2)<<endl;
        cout<<"<class T1, class 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<<"<class int, class double>"<<endl;        
    }
};


/*
template <class 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(void)
{
    MySimple<char, double> obj1;
    obj1.WhoAreYou();
    MySimple<int, long> obj2;
    obj2.WhoAreYou();
    MySimple<int, double> obj3;
    obj3.WhoAreYou();

    return 0;
}

 주석을 풀지 않은 출력값은 다음과 같다.

size of T1: 1
size of T2: 8
<class T1, class T2>
size of T1: 4
size of T2: 4
<class T1, class T2>
size of int: 4
size of double: 8
<class int, class double>

 주석을 풀면 다음과 같이 클래스 템플릿의 부분 특수화가 진행된 것을 확인할 수 있다. 또한, 부분 특수화와 전체 특수화 모두에 해당하는 객체 생성 문장에서는 전체 특수화된 클래스를 대상으로 객체가 생성됨을 통해, 전체 특수화가 부분 특수화보다 우선시됨을 알 수 있다.

size of T1: 1
size of double: 8
<T1, double>
size of T1: 4
size of T2: 4
<class T1, class T2>
size of int: 4
size of double: 8
<class int, class double>

 


참고자료

  • 윤성우, <윤성우의 열혈 C++ 프로그래밍>, 오렌지미디어, 2010.05.12