개요
일반적인 c++ 프로젝트에서 파일분할은 다음과 같다.
- 헤더파일(.h) : 클래스 선언
- 소스파일(.cpp) : 클래스 정의
그리고 헤더파일에서는 #include를 지양하고 cpp파일에서만 헤더파일을 include하는 식으로 의존성을 관리한다.
하지만 template의 경우 조금 다르기에 정리해보고자 한다.
Template의 파일 분할
만약 다음과 같이 파일을 분할 하였다면 코드는 다음과 같은 것이다.
- PointTemplate.h : 클래스 템플릿 선언
- PointTemplate.cpp : 클래스 템플릿 정의
- PointMain.cpp : 클래스 사용
PointTemplate.h
#pragma once
template <class T>
class Point{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0);
void ShowPosition() const;
};
PointTemplate.cpp
#include <iostream>
#include "PointTemplate.h"
using namespace std;
template <class T>
Point<T>::Point(T x, T y): xpos(x), ypos(y)
{ }
template <class T>
void Point<T>::ShowPostision() const{
cout << xpos << ", " << ypos << "\n";
}
PointMain.cpp
#include "PointTemplate.h"
int main() {
Point<int> pos1(3, 5);
Point<double> pos2(1.2, 3.5);
Point<char> pos3('A', 'B');
}
보기에는 파일분할도 잘하고 include도 잘한것으로 보인다. 하지만 컴파일 시 에러가 난다.
이유는 템플릿 클래스를 만드는 시점에 있다. c++은 각각의 .cpp 파일을 각자 컴파일하고 이를 링킹하는 작업을 최종 obj파일이 만들어진다.
하지만 템플릿의 경우 .cpp을 컴파일해도 클래스 템플릿이 컴파일 되는 것이지 탬플릿 클래스가 만들어지진 않는다.
탬플릿 클래스의 경우 PointMain.h에서 각 템플릿 클래스 객체를 만들때 인데 이때 템플릿 정의부가 없다면 템플릿 클래스를 만들 수 없다.
따라서 템플릿을 사용하기 위해서는 사용할 위치의 .cpp에서 헤더와 소스를 둘 다 include해야 정상적으로 작동한다.
수정한 PointMain.cpp
#include "PointTemplate.h"
#include "PointTemplate.cpp" //클래스 템플릿을 정의한 소스코드도 include
int main() {
Point<int> pos1(3, 5);
Point<double> pos2(1.2, 3.5);
Point<char> pos3('A', 'B');
}
PointTemplate.cpp만 추가로 include하면 작동한다.
'C++' 카테고리의 다른 글
[C++]STL stack (0) | 2024.12.29 |
---|---|
[C++] STL Map (1) | 2024.12.23 |
[C++] 템플릿의 특수화 (0) | 2024.12.23 |
[C++] unique_ptr, shared_ptr (1) | 2024.12.23 |
[C++] 연결 리스트 (1) | 2024.12.23 |