일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- PCA
- 티스토리챌린지
- regression
- OpenAI
- 해커톤
- Classification
- supervised learning
- GPT-4
- Machine Learning
- LLM
- deep learning
- 지도학습
- ChatGPT
- LG Aimers
- 머신러닝
- gpt
- AI
- 딥러닝
- 회귀
- 오블완
- LG Aimers 4th
- LG
- 분류
Archives
- Today
- Total
SYDev
C++ Chapter 13-2 : 클래스 템플릿(Class Template) 본문
클래스 템플릿의 정의
함수 템플릿과 마찬가지로 클래스도 템플릿화를 통해 별도의 클래스를 정의할 필요가 없어진다.
#include <iostream>
using namespace std;
template <typename T>
class Point
{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0) : xpos(x), ypos(y)
{ }
void ShowPosition() const
{
cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
}
};
int main(void)
{
Point<int> pos1(3, 4); //T를 int로 하여 만든 템플릿 클래스 Point<int>의 객체
Point<double> pos2(2.4, 3.6); //T를 double로 하여 만든 템플릿 클래스 Point<double>의 객체
Point<char> pos3('P', 'F'); //좌표정보를 문자로 표시하는 상황의 표현
pos1.ShowPosition();
pos2.ShowPosition();
pos3.ShowPosition();
return 0;
}
[3, 4]
[2.4, 3.6]
[P, F]
- 템플릿 함수의 호출과 달리 템플릿 클래스 객체의 생성에서는 <int>, <double>과 같은 자료형 정보를 생략할 수 없다.
클래스 템플릿의 선언과 정의의 분리
- 클래스 템플릿 내부에 선언한 멤버함수를 클래스 템플릿 외부에서 정의하려면, 해당 함수의 정의를 시작하기 전에 같은 클래스 템플릿 선언을 다시 해줘야 한다.
#include <iostream>
using namespace std;
template <typename T>
class Point
{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0);
void ShowPosition() const;
};
template <typename T>
Point<T>::Point(T x, T y) : xpos(x), ypos(y)
{ }
template <typename T>
void Point<T>::ShowPosition() const
{
cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
}
int main(void)
{
Point<int> pos1(3, 4);
Point<double> pos2(2.4, 3.6);
Point<char> pos3('P', 'F');
pos1.ShowPosition();
pos2.ShowPosition();
pos3.ShowPosition();
return 0;
}
[3, 4]
[2.4, 3.6]
[P, F]
파일 분할에서의 템플릿 클래스
- 템플릿 클래스가 정의되지 않은 일반적인 파일 분할의 경우에서는 함수의 선언과 정의를 헤더파일과 소스 파일나 나눠서 저장해도 main파일 실행에 문제가 없었다.
- 그러나, 템플릿 클래스의 경우에는 템플릿의 모든 정보를 소스파일에 전달해야 문제가 생기지 않는다.
그렇다면 위 예제를 분할하여 실행해보자.
파일명 : PointTemplate.h
#ifndef __POINT_H__
#define __POINT_H__
template <typename T>
class Point
{
private:
T xpos, ypos;
public:
Point(T x=0, T y=0);
void ShowPosition() const;
};
#endif
파일명 : PointTemplate.cpp
#include <iostream>
#include "PointTemplate.h"
using namespace std;
template <typename T>
Point<T>::Point(T x, T y) : xpos(x), ypos(y)
{ }
template <typename T>
void Point<T>::ShowPosition() const
{
cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
}
파일명 : PointMain.cpp
#include <iostream>
#include "PointTemplate.h"
#include "PointTemplate.cpp" //템플릿 정보를 모두 포함해야 함
using namespace std;
int main(void)
{
Point<int> pos1(3, 4);
Point<double> pos2(2.4, 3.6);
Point<char> pos3('P', 'F');
pos1.ShowPosition();
pos2.ShowPosition();
pos3.ShowPosition();
return 0;
}
[3, 4]
[2.4, 3.6]
[P, F]
배열 클래스의 템플릿화
class BoundCheckIntArray { . . . . };
class BoundCheckPointArray { . . . . };
class BoundCheckPointPtrArray { . . . . };
지금까지 배운 내용을 토대로 이전 chapter에서 등장한 위 세 클래스를 하나의 클래스 템플릿 정의로 대체해보자.
파일명 : ArrayTemplate.h
#ifndef __ARRAY_TEM__
#define __ARRAY_TEM__
#include <iostream>
#include <cstdlib>
using namespace std;
template <class T>
class BoundCheckArray
{
private:
T * arr;
int arrlen;
BoundCheckArray(const BoundCheckArray& arr) { }
BoundCheckArray& operator=(const BoundCheckArray& arr) { }
public:
BoundCheckArray(int len);
T& operator[] (int idx);
T operator[] (int idx) const;
int GetArrayLen() const;
~BoundCheckArray();
};
template <class T>
BoundCheckArray<T>::BoundCheckArray(int len) : arrlen(len)
{
arr = new T[len];
}
template <class T>
T& BoundCheckArray<T>::operator[](int idx)
{
if (idx < 0 || idx >= arrlen)
{
cout << "Array index out of bound exception" << endl;
exit(1);
}
return arr[idx];
}
template <class T>
T BoundCheckArray<T>::operator[](int idx) const
{
if (idx < 0 || idx >= arrlen)
{
cout << "Array index out of bound exception" << endl;
exit(1);
}
return arr[idx];
}
template <class T>
int BoundCheckArray<T>::GetArrayLen() const { return arrlen; }
template <class T>
BoundCheckArray<T>::~BoundCheckArray() { delete[] arr; }
#endif
파일명 : Point.h
#ifndef __POINT_H_
#define __POINT_H_
#include <iostream>
using namespace std;
class Point
{
private:
int xpos, ypos;
public:
Point(int x=0, int y=0);
friend ostream& operator<<(ostream& os, const Point& pos);
};
#endif
파일명 : Point.cpp
#include <iostream>
#include "Point.h"
using namespace std;
Point::Point(int x, int y) : xpos(x), ypos(y)
{ }
ostream& operator<<(ostream& os, const Point& pos)
{
os<<'['<<pos.xpos<<", "<<pos.ypos<<']'<<endl;
return os;
}
파일명 : BoundArrayMain.cpp
#include <iostream>
#include "ArrayTemplate.h"
#include "Point.h"
using namespace std;
int main(void)
{
/*** int형 정수 저장 ***/
BoundCheckArray<int> iarr(5);
for(int i=0; i<5; i++)
iarr[i] = (i+1)*11;
for(int i=0; i<5; i++)
cout<<iarr[i]<<endl;
/*** Point형 객체 저장 ***/
BoundCheckArray<Point> oarr(3);
oarr[0] = Point(3, 4);
oarr[1] = Point(5, 6);
oarr[2] = Point(7, 8);
for(int i=0; i<oarr.GetArrayLen(); i++)
cout<<oarr[i];
/*** Point형 객체의 주소 값 저장 ***/
typedef Point * POINT_PTR;
BoundCheckArray<POINT_PTR> parr(3);
parr[0] = new Point(3, 4);
parr[1] = new Point(5, 6);
parr[2] = new Point(7, 8);
for(int i=0; i<parr.GetArrayLen(); i++)
cout<<*(parr[i]);
delete parr[0];
delete parr[1];
delete parr[2];
return 0;
}
첫 번째 트라이에서는 혼자서 작성하기 많이 힘들었지만, 두 번째 트라이부터 할만해져서 다행이었다.....
참고자료
- 윤성우, <윤성우의 열혈 C++ 프로그래밍>, 오렌지미디어, 2010.05.12
728x90
반응형
'Programming Lang > C++' 카테고리의 다른 글
C++ Chapter 14-2 : 클래스 템플릿의 특수화(Class Template Specialization) (0) | 2023.07.31 |
---|---|
C++ Chapter 14-1 : Chapter 13 내용의 확장 (0) | 2023.07.31 |
C++ Chapter 13-1 : 템플릿(Template)에 대한 이해와 함수 템플릿 (0) | 2023.07.27 |
C++ Chapter 12-2 : 문자열 처리 클래스의 정의 (0) | 2023.07.26 |
C++ Chapter 12-1 : C++의 표준과 표준 string 클래스 (0) | 2023.07.26 |