티스토리 뷰
클래스 템플릿
- '클래스 템플릿'은 클래스를 찍어내는 모양자라고 생각하면 이해하기 쉽다. 그리고 이 모양자에 구멍이 뚫려 있는 부분은 '자료형'이다. 클래스 템플릿은 다음과 같인 선언할 수 있다.
template<typename T>
class 클래스명 {
.....
}
함수 템플릿처럼 선언에 앞서 template 예약어와 tpyename 예약어를 적어 넣어야한다. 그러나 함수 템플릿과 달리 인스턴스를 선언할떄는 typename을 반드시 적어야 한다.
template<typename T>
class MyData
{
public(T param) : m_Data(param) { }
T GetData() const { return m_Data; }
operator T() { return m_Data; }
void SetData(T param) { m_Data = param; }
private :
// T 형식의 멤버 변수 선언
T m_Data;
]
int _tmain(int argc_ TCJAR* argv[])
{
CMyData<int> a(5);
cout << a << endl;
CMyData<double> b(123.45);
cout << b << endl;
CMyData<char*> c("Hello");
cout << c << endl;
return 0;
}
이러한 예제 소스가 있을때 굵게 칠해진 행을 보면 클래스 템플릿으로 인스턴스를 선언할때 각각에 맞는 자료형을 정의했다 .이렇게 하면 int, double, char*에 맞는 클래스를 컴파일러가 찍어낸다. 참고로 찍어서만드어진 클래스를 '템플릿 클래스'라고 한다.
Template 이라는 단어는 모형자라는 의미를 가진단어로, C++에서 템플릿은 어떤 제품을 만들어내는 틀, 예를 들어 붕어빵에 비교해 보자면, 붕어빵을 만들어 내는 틀을 템플릿이라 말 할 수 있다. 템플릿의 특징은 기능은 이미 결정되어 있지만, 데이터 타입은 결정되어 있지 않는다는 특징을 가지고 있다. 생성된 세 템플릿 클래스는 모두 동일하게 변환 생성자, 형변환 연산자, SetData() 메서드를 가진다.
템플릿 매개변수
템플릿을 선언할 때 다음과 같이 형식을 여러개 작성할 수도 있습니다.
Template<Typename T, tpyename T2>
그런데 여러 형 식 중 일부는 다음과 같이 형식을 구체적으로 작성해도 상관없다.
Template<Typename T, int nSize>
tmeplate<typename T, int nSize>
class CMyArray{
......
}
int _tmaint(int argc, _TCJAR* argv[])
{
CMyArray<int, r> arr;
arr[0] = 10;
arr[1] = 20;
arr[3] = 30;
...
}
tmeplate<typename T, int nSize>라고 선언했고 CMyArray<int, 3> arr; 라고 선언했다. 이렇게 함으로 arr 요소의 개수는 3이된다. 여기서 재밌는 사실은 템플릿 매개변수는 클래스 템플릿 내부에서도 모두 접근할 수 있다는 점이다.
템플릿 특수화
- 템플릿을 사용하면 자료형에 관계없이 프로그램을 만들 수 있따. 그러나 간혹 특별한 형식이 있을 경우 나머지 다른 형식들과 전혀 다른 코드를 적용해야 할 때가 있씁니다. 가장 대표적인 예인 '포인터'는 일반적인 형식들과 달리 간접 지정 연산을 실행해야하는 경우가 있다. 또한 문자열에 '덧셈'을 적용할 경우 일반 형식과 전혀 다른 코드를 작성해야 한다.
함수 템플릿 특수화
template<typename T>
T Add(T a,T b) {
return a + b;
}
template<>
char* Add(char *pszLeft, char *pszRight)
{
int nLenLeft = strlen(pszLeft);
int nLenRight = strlen(pszRight);
char *pszResult = new char[nLenLeft + nLenRight = 1];
strcpy_s(pszResult, nLenLeft + 1, pszLeft);
strcpy_s(pszResult + nLenLeft, nLenRight + 1, pszRight);
return pszResult;
}
int _tmain(int argc, _TCHAR* argv[])
{
int nResult = Add<int>(3, 4);
cout << nResult << endl;
char *pszResult = Add<char*>("hello", "world");
cout << pszResult << endl;
delete [] pszResult
return 0;
}
위으 소스는 함수 템플릿인 Add()를 두가지 형태로 정의한 것이다. 여기서 두가지라고 한 것은 문자열을 더하는 경우와 나머지 모든 자료형을 위한 경우로 나눈 것이다. 한마디로 문자열을 특별히 분리해서 (특수화해서) 처리하는 것이다.
int nResult = Add<int>(3, 4); 호출한 Add() 템플릿 함수는 첫번째 함수에서 만들어지고 char *pszResult = Add<char*>("hello", "world"); 는 두번째 add 함수로 생성된다.
템플릿을 특수화할 때 typename을 아무것도 기술하지 않았다. 마치 함수를 다중 정의하듯 함수 템플릿을 여러 번 정의하는 경우 컴팡일러는 이를
"특정 형식은 개발자인 내가 직접 정의할 테니 별도로 생성하지 말라"
는 것으로 인식한다. 다만 이와 같이 묵시적 의미가 전달되려면 두 매개 변수와 변환 형식이 모두 같아야한다.
'C++' 카테고리의 다른 글
JNI 변수 타입 및 시그니처 정보 (JNI Signiture) (0) | 2018.08.12 |
---|---|
JNI를 이용하여 JAVA함수를 C++에서 사용해보자 (구현) JNI INVOKE (3) | 2018.08.10 |
JNI를 이용하여 JAVA함수를 C++에서 사용해보자 (셋팅) JNI INVOKE (0) | 2018.08.03 |
OSI 7계층, TCP/IP 4계층 (0) | 2018.05.17 |
[C++] 가상함수 (Virtual) (0) | 2018.05.14 |
- Total
- Today
- Yesterday
- React.js
- 다클 빈
- JNI SIGNITURE
- 다클 코드
- JNI 시그니처
- lxd
- Linux
- EACCES: permission denied
- 대항해시대
- 대항해시대 로그인
- HTTPie
- 정보처리기사 2018 2회
- JNI INVOKE
- JNI
- 데스큐어
- 대항해시대 넷마블 런처
- 구글 클라우드 플랫폼
- 정처기 실기
- 대항해시대 런처
- 위대한 쇼맨
- 폴더선택다이얼로그
- 대항해시대 다클
- 합격 후기
- OSI 7Layer
- 빈파일
- vite.js
- 위대한 쇼맨 ost
- 위대한 쇼맨 후기
- 정보처리기사 실기 후기
- 대항해시대 다음 런처
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |