일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- C++
- Time
- 도움말
- 핵심 요약
- Tipsware
- C
- 충무창업큐브
- MFC 예제
- 마이크로소프트
- mfc 실습
- ListBox
- 실습
- 유료강좌
- 정처기 독학
- MyThread
- 별찍기
- mysql
- SSG
- MyTread
- MFC
- do it c
- 포트폴리오
- C언어
- 정보처리기사
- tips강좌
- win32
- 미가공
- visual
- 김성엽
- linux
- Today
- Total
History
[C++] 템플릿(template)에 대하여 step2 본문
저번차시에 이어서 템플릿에 대한 글을 작성해 보겠다.
저번엔 템플릿을 활용한 Swap기능을 하는 제네릭 함수를 만들었다.
이번에는 배열에 저장된 정수를 더하는 제네릭 함수를 실습해 본다.
#include<iostream>
using namespace std;
//타입 T의 배열 arr에서 n개의 원소를 합한 결과
//리턴 타입이 모두 T임
template<class T>
T Add(T *arr,int n)
{
T sum=0;
for(int i=0; i<n; i++){
sum+=data[i];
}
return sum;
}
int main()
{
int x[10]={1,2,3,4,5,6,7,8,9};
float x2[10]={1.1,2.2,3.1,4.3,5.5,6.8,7.41,8.2,9.6};
cout<<"sum of x"<<add(x,10)<<"\n";
cout<<"sum of x2"<<add(x2,10)<<"\n";
}
이번엔 2개 이상의 제네릭 타입을 가진 경우이다. 아래 코드를 보고 코드에 대한 설명을 이어가겠다.
#include<iostream>
using namespace std;
//타입 T의 배열 arr에서 n개의 원소를 합한 결과
//리턴 타입이 모두 T임
template<class T1, class T2>
void DataCopy(T1* arr, T2* arr2, int n)
{
for (int i = 0; i < n; i++) {
arr2[i] = (T2)arr[i];
}
}
int main()
{
int x[10] = { 1,2,3,4,5,6,7,8,9 };
char x2[10] = { 'a','b','c','d','e','f','g','h','i','j' }, x3[10];
float x4[10];
DataCopy(x, x4, 10);
DataCopy(x2, x3, 10);
for (int i = 0; i < 10; i++) {
cout << x3[i] << " ";
}
cout << "\n";
for (int i = 0; i < 10; i++) {
cout << x4[i] << " ";
}
cout << "\n";
}
이처럼 원본과 사본의 배열 타입이 달라도 컴파일러는 DataCopy함수로 들어온 인자값으로 상황을 판단하여 각자에 맞는 코드로 구체화한다.
중복함수가 템플릿 함수보다 우선.
모든 데이터를 출력하는 함수를 정의했다고 가정하자.
나는 int, float, double, char 등 다양한 변수를 출력하는 print함수를 만들 것이다. 그러나 템플릿으로 이 함수를 구현하면 char형에서는 그래픽 문자가 출력된다. 왜냐하면 정수 1~5에 해당하는 ASCII 문자가 없기 때문에 윈도우 운영체제의 문자 코드표에 정의된 다음에 출력하기 때문이다. 그렇기 때문에 char형만 따로 출력하는 일반 함수를 만들 것이다. 이렇게 하면 중복된 함수가 2개가 나오는데 같은 이름의 중복함수를 호출하면 제네릭 함수보다 일반함수가 우선 호출이 되기 때문에 이런 상황에서는 사용이 가능하다.
#include<iostream>
using namespace std;
//타입 T의 배열 arr에서 n개의 원소를 합한 결과
//리턴 타입이 모두 T임
template<class T>
void print(T* arr, int n)
{
for (int i = 0; i < 5; i++) {
cout << arr[i] << " ";
}
cout << "\n";
}
void print(char* arr, int n)
{
for (int i = 0; i < 5; i++) {
cout << (int)arr[i] << " ";
}
cout << "\n";
}
int main()
{
int x[5] = { 1,2,3,4,5 };
float x2[5] = { 1.1,2.2,3.3,4.41,5.5 };
print(x, 5);
print(x2, 5);
char x3[5] = {'a','b','c','d','e'};
print(x3, 5);
}
제네릭 클래스 만들기
템플릿을 이용하면 제네릭 클래스도 만들 수 있다. 예를 들면 스텍이라는 자료구조가 있다. 우리는 보통 int 타입의 데이터를 쌓을 때 int형 스텍을 만들고 char형은 char형 스텍 등등 다양한 자료형을 넣기 위해서는 각각의 형에 맞는 스텍을 만들어야 한다. 그러나 템플릿을 이용한다면 이러한 중복 코드들을 한 번에 없앨 수 있다.
제네릭 클래스의 선언은 아래와 같다.
template<class T>
class Stack{
private:
int top;
T data[100]; //100개의 원소를 넣을 수 있는 스택
public:
Stack();
void push(T a_data); //T타입의 데이터를 푸스한다.
T pop(); //스택의 탑에 있는 원소를 data배열에서 꺼내서 리턴한다.
}
클래스의 구현부는 아래와 같다.
template<class T>
void Stack<T>::push(T a_data){
}
template<class T> //항상 각 함수의 선언부에 붙혀줘야함.
T Stack<T>::pop(){
}
이렇게 구현된 함수들은 아래와 같이 사용하면 된다.
int main()
{
Stack<int> istack; //int타입의 스택
Stack<float> fstack; //float타입의 스택
Stack<char> *p_cstack=new Stack<char>; //chart타입의 스택
istack.push(3);
int a=istack.pop();
fstack.push(3.7);
float b=fstack.pop();
p_cstack->push('a');
char c=p_cstack->pop();
delete p_cstack;
}
제네릭 클래스를 사용할 때는 클래스의 이름과 함께 제네릭 타입 T에 적용할 구체적인 타입을 지정해야 한다.
2개의 제네릭 타입을 가진 클래스 만들기.
#include<iostream>
using namespace std;
template<class T1, classT2>
class GClass{
private:
T1 m_data1;
T2 m_data2;
public:
GClass();
~GClass();
}
template<class T1, classT2>
GClass<T1,T2>GClass() //생성자
{
m_data1=0;
m_data2=0;
}
template<class T1, classT2>
void GClass<T1,T2>::Set(T1 a_data1,T2 a_data2)
{
m_data1=a_data1;
m_data2=a_data2;
}
template<class T1, classT2>
void GClass<T1,T2>::Get(T1 *a_data1,T2 *a_data2) //void말고 int return형으로 만들어도 된다.
{
*a_data1=m_data1;
*a_data2=m_data2;
}
int main()
{
int a;
double b;
GClass<int, double> x;
x.Set(2,0.5);
x.Get(&a,&b);
cout<<"a="<<a<<"b="<<b<<endl;
char c;
float d;
GClass<char, float> y;
x.Set('q',10.5);
x.Get(&a,&b);
cout<<"c="<<c<<"d="<<d<<endl;
return 0;
}
'C,C++ > 개념 실습 프로그래밍' 카테고리의 다른 글
[c언어] 소숫점 반올림(첫째, 둘째... 자리) (0) | 2023.10.24 |
---|---|
[c++] STL에 관한 기초 개념 (0) | 2023.06.03 |
[C++] 템플릿(template)에 대하여 step1 (0) | 2023.05.16 |
[C언어] 파일에 저장된 문자열 수정하기 (0) | 2023.04.26 |
[C언어] fgets 함수에 대하여 (0) | 2023.04.26 |