템플릿(Template) - 2
이번엔 클래스 템플릿, 템플릿 클래스에 대해 알아보자.
이전에 함수 템플릿, 템플릿 함수를 생각해본다면 바로 무엇인지 감이 올 것이라 생각된다.
Ex>
class Point
{
private:
int xpos, ypos;
public:
Point(int x = 0, int y = 0) : xpos(x), ypos(y) { }
void ShowPosition() const
{
cout << '[' << xpos << ", " << ypos << ']' << endl;
}
};
위와 같은 클래스가 있을 때 좌표를 double, char 형으로도 사용하게끔 하려면 두가지를 더 정의해야한다. 이 때 템플릿화 하면
더 정의를 할 필요가 없어진다.
Ex>
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;
}
};
위처럼 정의해주면 된다. 사용하는 방법을 보면
Ex>
int main(void)
{
Point<int> pos1(5, 4);
pos1.ShowPosition();
Point<double> pos2(3.4, 5.6);
pos2.ShowPosition();
Point<char> pos3('A', 'Z');
pos3.ShowPosition();
return 0;
}
-출력 화면
[5, 4]
[3.4, 5.6]
[A, Z]
함수 템플릿과 사용 방법은 거의 동일하다. 하지만 클래스 템플릿의 경우 <int>, <double>등 자료형 생략이 불가능하다. 클래스 템플릿 기반의 객체 생성에서는 자료형을 반드시 명시해야한다.
함수 템플릿과 템플릿 함수와 마찬가지로 클래스 템플릿은 만들어 낼 클래스의 정의, 틀 이고 템플릿 클래스는 클래스 템플릿을 통해 만들어진 클래스를 말한다.
클래스 템플릿에서도 멤버 함수를 클래스 외부에 정의하는 것이 가능하다.
Ex>
template <typename T>
class SimpleTemplate
{
public:
T SimpleFunc(const T& ref);
};
외부..
template <typename T>
T SimpleTemplate<T>::SimpleFunc(const T& ref);
{
...
}
일반적인 클래스 정의와 외부에 멤버 함수를 정의하는 방법과 크게 다르지 않다. 함수 헤더 위에 template<typename T>를 붙여주고 반환형과 소속(SimpleTemplate)를 써주고 클래스 템플릿 내부에서 선언한 헤더를 써주면된다.
외부에 정의하는 방법을 배웠고 그다음으로는 파일 분할시에 문제점과 해결책을 알아보겠다.
위에서 외부에 함수 정의도 별 다를게 없는데 파일 분할도 다를게 없겠다 싶겠지만 컴파일을 하면 문제가 발생한다.
파일단위로 컴파일을 하기때문에 .h파일에 선언만 해놓고 .cpp파일에 정의를 하면 먼저 .h파일을 컴파일 하고 .cpp 파일을 할 때는 문제가 없다. 그러나 main으로 넘어가서 컴파일을 하면 .h파일의 내용은 알고 있으나 .cpp에 정의한 내용을 알지 못하는 것이다.
이게 무슨 뜻인지 풀어설명하면 .h파일을 main에서 #include 를 하면 main에서 컴파일시에 .cpp의 정의와는 상관 없이 .h에 선언이 되어있기 때문에 내용은 알 수 없으나 일단 있다는 것만 알고 넘어가겠다는 뜻이다. 그렇기 때문에 일반 사용자 정의 함수나 클래스에서 파일 분할을 하여도 문제가 없는데 함수 템플릿이나 클래스 템플릿의 경우 컴파일 과정에서 호출에 따라 템플릿 함수와 템플릿 클래스를 만들어두어야한다. 그렇다는 말은 있다는 건 알겠으니 넘어가는 것이 아니라 뭔지 알고 만들어 놓아야한다. 그렇기 때문에 이를 해결하기 위해서는 .h파일에 정의도 함께 두거나 #include 로 템플릿 정의가 담긴 .cpp 파일을 포함하여야한다.
- 출처 : 윤성우 열혈 C++ 프로그래밍