C++ - 템플릿(template)
내장형 하드웨어/C++ / 2011. 11. 21. 15:54
- 템플릿(tempate)
→ 모든 형을 다 선언할 수 있는 클래스
→ template <class T> 와 같은 형태로 선언한다.
#include<iostream.h>
template <class T>
class array
{
private:
T *item;
int iNum;
array() // 디폴트 생성자
{
}
array(array &r) // 복사 생성자
{
}
array& operator =(array &r) // 대입 연산자
{
return *this;
}
public:
array(int iNum) // 인자가 하나인 생성자
{
this->iNum = iNum;
item = new T[iNum];
for(int iCnt = 0; iCnt<iNum; ++iCnt)
{
item[iCnt] = 0;
}
cout << "인자가 1개인 array 생성자" << endl;
}
void print();// print()
~array() // 소멸자
{
delete [] item;
cout << "array 소멸자 " << endl;
}
// T는 컴파일하면 int로 바뀐다.
// main()에서 <int> 선언했기 때문
void setMember(int iNum, T value)
{
if(this->iNum<=iNum)
{
return ;
}
// iNum 자리(배열)의 값을 value로 바꾼다.
item[iNum] = value;
return ;
}
};
template <class T>
void array<T>::print() // print()
{
for(int iCnt = 0;iCnt<iNum;++iCnt)
{
cout << item[iCnt] << " ";
}
cout << endl;
return ;
}
int main()
{
array <int> OBJ1(5);
// 두번째 인자가 int가 아니지만 동작한다.-template
OBJ1.setMember(3, 2);
OBJ1.print();
// <float> 으로 바꾸었다.
// 따라서 출력 결과는 item[3]자리에 3.1이 출력된다.
array <float> OBJ2(6);
OBJ2.setMember(3, 3.1f);
OBJ2.print();
return 0;
}
→ array <int> OBJ1(5); 와 같이 선언한다.template <class T>
class array
{
private:
T *item;
int iNum;
array() // 디폴트 생성자
{
}
array(array &r) // 복사 생성자
{
}
array& operator =(array &r) // 대입 연산자
{
return *this;
}
public:
array(int iNum) // 인자가 하나인 생성자
{
this->iNum = iNum;
item = new T[iNum];
for(int iCnt = 0; iCnt<iNum; ++iCnt)
{
item[iCnt] = 0;
}
cout << "인자가 1개인 array 생성자" << endl;
}
void print();// print()
~array() // 소멸자
{
delete [] item;
cout << "array 소멸자 " << endl;
}
// T는 컴파일하면 int로 바뀐다.
// main()에서 <int> 선언했기 때문
void setMember(int iNum, T value)
{
if(this->iNum<=iNum)
{
return ;
}
// iNum 자리(배열)의 값을 value로 바꾼다.
item[iNum] = value;
return ;
}
};
template <class T>
void array<T>::print() // print()
{
for(int iCnt = 0;iCnt<iNum;++iCnt)
{
cout << item[iCnt] << " ";
}
cout << endl;
return ;
}
int main()
{
array <int> OBJ1(5);
// 두번째 인자가 int가 아니지만 동작한다.-template
OBJ1.setMember(3, 2);
OBJ1.print();
// <float> 으로 바꾸었다.
// 따라서 출력 결과는 item[3]자리에 3.1이 출력된다.
array <float> OBJ2(6);
OBJ2.setMember(3, 3.1f);
OBJ2.print();
return 0;
}
→ <int>로 T 부분은 모두 int 형이 된다.
→ <float>로 T 부분은 모두 float 형이 된다.
→ 자료기반의 언어(C 언어)에서 형이 바뀌면 함수를 그대로 복사하여 형을 바꾸는 등으로 사용해야 했다면 template를 사용하여 여러가지 형을 사용할 수 있다.
→ 실행 결과
※ cat main10.cpp >> main11.cpp
→ 리눅스에서 위와 같은 명령으로 main11.cpp 파일의 내용에 main10.cpp의 내용을 추가(덧붙일 수)할 수 있다.
→ template는 클래스도 집어 넣을 수 있다.
→ 즉 모든 클래스를 다 사용할 수 있다.
→ 예로 이전에 emb 클래스를 사용한다. templet을 emb 타입으로 하여 실행시켜 보면
→ array <emb> OBJ1(10); // 배열 10개를 가지는 객체 생성
→ emb형 temp 변수를 만들어 값을 대입하고 이를 OBJ1.setMember(3, temp); 의 형식으로 입력한다.
→ 실행 결과
→ 실행 결과를 확인해 보면 4번째 emb 멤버 변수 출력에서 값 A, B, C, D가 모두 100으로 바뀐것을 확인할 수 있다.※ cat main10.cpp >> main11.cpp
→ 리눅스에서 위와 같은 명령으로 main11.cpp 파일의 내용에 main10.cpp의 내용을 추가(덧붙일 수)할 수 있다.
→ template는 클래스도 집어 넣을 수 있다.
→ 즉 모든 클래스를 다 사용할 수 있다.
→ 예로 이전에 emb 클래스를 사용한다. templet을 emb 타입으로 하여 실행시켜 보면
int main()
{
array <emb> OBJ1(10);
emb temp;
temp = 100;
OBJ1.setMember(3, temp);
cout << OBJ1 << endl;
return 0;
}
{
array <emb> OBJ1(10);
emb temp;
temp = 100;
OBJ1.setMember(3, temp);
cout << OBJ1 << endl;
return 0;
}
→ array <emb> OBJ1(10); // 배열 10개를 가지는 객체 생성
→ emb형 temp 변수를 만들어 값을 대입하고 이를 OBJ1.setMember(3, temp); 의 형식으로 입력한다.
→ 실행 결과
- 가상함수
// 가상함수
#include<iostream.h>
class Musician
{
private:
public:
// virtual - 각각의 자식 클래스들을 사용하게 해 준다.
// 오버 라이딩
virtual void greet() // MFC에서 매우 중요한 기법
{
cout << "안녕하세요 저는 뮤지션입니다." << endl;
}
};
class Singer:public Musician
{
private:
public:
void greet()
{
cout << "안녕하세요 저는 싱어입니다." << endl;
}
};
class Drum:public Musician
{
private:
public:
void greet()
{
cout << "안녕하세요 저는 드러머입니다." << endl;
}
};
class Bell:public Musician
{
private:
public:
void greet()
{
cout << "안녕하세요 저는 벨 연주자입니다." << endl;
}
};
int main()
{
Musician M;
Singer S;
Drum D;
Bell B;
Musician *P[4] = {&M, &S, &D, &B}; // 각각을 초기화
for(int iCnt = 0 ; 4>iCnt ; ++iCnt)
{
(*P[iCnt]).greet();
}
/*
M.greet();
S.greet();
D.greet();
B.greet();
*/
return 0;
}
→ 최상위 클래스인 Musician의 중복 사용을 위한 void greet(); 앞에 virtual을 붙여준다.#include<iostream.h>
class Musician
{
private:
public:
// virtual - 각각의 자식 클래스들을 사용하게 해 준다.
// 오버 라이딩
virtual void greet() // MFC에서 매우 중요한 기법
{
cout << "안녕하세요 저는 뮤지션입니다." << endl;
}
};
class Singer:public Musician
{
private:
public:
void greet()
{
cout << "안녕하세요 저는 싱어입니다." << endl;
}
};
class Drum:public Musician
{
private:
public:
void greet()
{
cout << "안녕하세요 저는 드러머입니다." << endl;
}
};
class Bell:public Musician
{
private:
public:
void greet()
{
cout << "안녕하세요 저는 벨 연주자입니다." << endl;
}
};
int main()
{
Musician M;
Singer S;
Drum D;
Bell B;
Musician *P[4] = {&M, &S, &D, &B}; // 각각을 초기화
for(int iCnt = 0 ; 4>iCnt ; ++iCnt)
{
(*P[iCnt]).greet();
}
/*
M.greet();
S.greet();
D.greet();
B.greet();
*/
return 0;
}
→ virtual void grret();
→ 이렇게 하면 클래스 포인터 타입인 Musician의 greet() 함수만 출력되던 결과가 전체 상속받은 클래스들의 값들로 바뀌어 출력되는 것을 확인 할 수 있다.
→ 즉, 부모 포인터를 가지면 부모만 출력되던 결과에서 virtual을 사용하므로서 자식들을 각각 가리켜 출력되게 한다.
'내장형 하드웨어 > C++' 카테고리의 다른 글
C++ - 참조, 복사 생성자, 연산자(operator) 오버로딩 (0) | 2011.11.17 |
---|---|
C++ 배열 포인터 복습 (0) | 2011.11.16 |
C++ - 객체 소멸 순서, 객체 생성(정적, 동적 할당-malloc, new) (0) | 2011.11.15 |
C++ - car class 추가, 다중상속, 유도(derivation), 타입 (0) | 2011.11.14 |
C++ 생성자, 소멸자, 상속 (0) | 2011.11.11 |