열혈 강의 12장 : 템플릿
template <typename T>
T Add(T a, T b){
return a+b;
}
쉽게 말해 자료형을 결정 짓지 않는 것.
1. 함수 템플릿
2. 템플릿 함수 --> 함수 템플릿에 의해 실제 호출이 가능한 함수.
template <typename T>
void show(T a, T b){
cout<<a<<' '<<b<<endl;
}
int main(){
show(5, 5.5); --> 컴파일 에러, 어느 장단에 맞춰야 할지 모른다.
}
======================= 해결책
template <typename T1 , tepename T2>
void show (T1 a, T2 b){ ... } --> 두개의 템플릿을 선언해 준다.
2. 함수 템플릿의 특수화
template <typename T>
void SizeOf(T a){
cout<<sizeof(a)<<endl;
}
int main(){
int a = 10;
float f = 10f;
double d = 10.0;
char* name = "name";
SizeOf(a); /// 4
SizeOf(f); /// 4
SizeOf(d); /// 8
SizeOf(name); ///4 --------> 포인터의 크기가 출력된다. 함수 내에서 return strlen(name); 이 반환되기를 원할 것이다.
}
============================해결책
tempalte<typename T>
void SizeOf(T a) { ... }
template<> -------------> 특수화, 원래는 한줄에 같이 쓴다. template<> void SizeOf(char* _name) { ... }
void SizeOf(char* _name){
return strlen(_name);
}
--> template<> void SizeOf<char*> (char* _name){ ... } --> 올바른 선언 방법
3. 클래스 템플릿
template<typename T> --> 다음에 정의하는 클래스를 템플릿화 하겠다.
class Data{ --> 클래스가 아니라 템플릿이다.
private:
T data;
public:
Data(T a) { data = a; }
T GetData(){ return data; }
void SetData(T a){ data = a; }
};
int main(){
Data<int> d1(0);
Data<char> d2('a');
}
----> 객체 생성 시 결정하고자 하는 자료형을 명시적으로 선언해 주어야 한다.
--> 객체 생성 순서 --> 메모리 할당 --> 생성자 호출
--> 메모리 공간의 할당이 우선적으로 진행되어야 하기 때문에 T의 자료형을 알고 있어야 한다.
--> 때문에 명시적으로 선언을 해주어야 한다.
선언과 정의 분리
template<typename T>
Data<T>:: Data(T a) { data = a; }
template<typename T>
T Data<T>:: GetData() { return data; }
teplate <typename T>
void Data<T>:: SetData(T a) { data = a; }
--> 멤버 함수를 정의할 때마다 반드시 붙여 줘야 한다.
--> Data<T> --> 클래스 Data가 아닌 클래스 템플릿 Data를 의미한다.
4. 스택 클래스의 템플릿화
template <typenaem T>
class Stack{
private:
int len;
T* data;
public:
Stack() : len (-1) { data = new T[100]; }
void push(T a);
T pop();
}
template <typename T>
void Stack<T>:: push(T a){ data[++len] = a; }
tempalte <typename T>
T Stack<T>:: pop() { return data[len--]; }
int main(){
Stack<int> a;
a.push(10);
a.push(20);
Stack<char> c;
c.push('a');
c.push('b');
}
5. 템플릿의 원리 이해
--> 템플릿 함수의 인스턴스화
--> 템플릿 클래스의 인스턴스화
template<typename T>
T Add(T a, T b){
return a+b;
}
--> 메인 에서 int형으로 호출했을 경우
int Add(int a, int b){
return a+b;
}
--> 메인에서 double형으로 호출했을 경우
int Add(char a, char b){
return a+b;
}
--> 와 같은 함수가 만들어 진다. --> 템플릿을 기반으로 함수가 만들어진다. (컴파일러에 의해)
--> 다음 번에 또 int 형으로 불려졌을 때, 다시 만들어지지 않고 만들어져 있는 놈이 불려온다.
--> double형으로 호출 했을 경우 위와 같이 double형으로 함수 템플릿이 인스턴스화 된다.
--> 클래스도 똑같은 원리
--> 이와 가이 함수 템플릿을 기반으로 실제 호출이 가능한 함수들을 가리켜 템플릿 함수라고 한다.
--> 함수가 만들어 지는 현상을 가리켜서 함수 템플릿의 인스턴스화 라고 부른다.
--> 템플릿은 컴파일러에 의해 처리된다.
--> 따라서 헤더와 정의를 분리할 수 없다. --> 분리 컴파일을 가능하게 하는 것은 링커이기 때문에
--> 하나의 파일 내에 정의와 선언이 같이 있어야 한다.
'C++' 카테고리의 다른 글
[C++] API란? (0) | 2016.12.15 |
---|---|
[C++] 예외처리 // 열혈강의 (0) | 2016.12.14 |
[C++] 복사생성자 정리 (0) | 2016.12.07 |
[C++] 레퍼런스 정리 (0) | 2016.12.07 |
[C++] 연산자 오버로딩 // 열혈강의 (0) | 2016.12.07 |