#클래스 템플릿(class template)
템플릿은 컴파일시 내부적으로 템플릿 인자로 넘어온 자료형을 적용하여 새로운 클래스를 하나 생성하게 된다. 그리고 컴파일러는 생성한 클래스를 가지고 작업을 수행하게 된다. 템플릿 클래스는 선언시 자료형에 상관없는 범용클래스로 만든후 객체 생성시 자료형을 지정해주면, 지정한 자료형에 맞는 클래스 인스턴스가 생성된다.
template <typename 식별자> 클래스 { //클래스 정의
//내용
};
template <typename 식별자>
void 클래스명<식별자>::멤버함수() { // 맴버 함수 구현
//내용
}
//***************************************************************************
// 템플릿 클래스 !!
//***************************************************************************
#include <iostream>
using namespace std;
// 배열 추상화 !!
// 1) 속성!!
// --> Data buffer !!
// --> 배열의 길이
// 2) 행동 !!
// --> 입력
// --> 삭제
// --> 출력
template <typename T>
class Array
{
private :
T *m_Buf;
int m_size;
public :
Array()
{
cout << "최대 배열의 크기 입력 ";
cin >> m_size;
m_Buf = new int[sizeof(T)]();
//memset(m_Buf,0,40);//******************//
menu();
}
~Array(){}
int & operator[](int idx)
{
return m_Buf[idx];
}
void push_back()
{
if(m_Buf[m_size-1] !=0){
m_Buf = (int *)realloc(m_Buf,_msize(m_Buf)+4);
m_size = _msize(m_Buf)/sizeof(int);
cout << "맨뒤에 넣을 값을 입력 ";
cin >> m_Buf[m_size-1];
}
else{
cout << "맨뒤에 넣을 값을 입력 ";
cin >> m_Buf[m_size-1];
}
}
void pop_back()
{
m_Buf[m_size-1] = 0;
cout << "["<< m_size << "]" << "맨뒤에 배열의 값을 뿅~~~~~" << endl;
m_Buf = (int *)realloc(m_Buf,_msize(m_Buf)-4);
m_size = _msize(m_Buf)/sizeof(int);
}
void push_front()
{
if(m_Buf[0] !=0){
m_Buf = (int *)realloc(m_Buf,_msize(m_Buf)+4);
m_size = _msize(m_Buf)/sizeof(int);
m_Buf[m_size-1] = 0;
for(int i=m_size;i>0;i--){
m_Buf[i-1] = m_Buf[i-2];
}
cout << "맨앞에 넣을 값을 입력 ";
cin >> m_Buf[0];
}
else{
cout << "맨앞에 넣을 값을 입력 ";
cin >> m_Buf[0];
}
}
void pop_front()
{
//cout << "맨앞에 배열의 값을 뿅~~~~~" << endl;
for(int i=0;i<m_size;i++){
m_Buf[i] = m_Buf[i+1];
}
m_Buf = (int *)realloc(m_Buf,_msize(m_Buf)-4);
m_size = _msize(m_Buf)/sizeof(int);
cout << "["<< 0 << "]" << "맨앞에 배열의 값을 뿅~~~~~" << endl;
}
void Add()
{
int num=0;
cout << "몇번째 ?? " <<endl;
cin >> num;
if(m_Buf[num-1] !=0){
m_Buf = (int *)realloc(m_Buf,_msize(m_Buf)+4);
m_size = _msize(m_Buf)/sizeof(int);
m_Buf[m_size-1] = 0;
for(int i=m_size;i>num-2;i--){
m_Buf[i-1] = m_Buf[i-2];
}
cout<< "숫자 입력 ";
cin >> m_Buf[num-1];
}
else{
cout<< "숫자 입력 ";
cin >> m_Buf[num -1];
}
}
void Pop_Select()
{
}
void Show()
{
for(int i=0;i<m_size;i++){
cout <<" "<< "["<< m_Buf[i] <<"]" ;
}
cout << endl;
}
void ascending_selection_sort () // 오름차순
{
cout << " 오름 차순 "<< endl;
int i, j, min;
for ( i = 0; i < m_size-1; i++ )
{
for ( min = i+1, j = i+2; j < m_size; j++ )
if ( m_Buf[min] > m_Buf[j] ) min = j;
if ( m_Buf[min] < m_Buf[i] ){
int t = m_Buf[i]; m_Buf[i] = m_Buf[min]; m_Buf[min] = t;
}
}
Show();
}
void descending_selection_sort () // 내림차순
{
cout << " 내림 차순 " << endl;
int i, j, max;
for ( i = 0; i <m_size-1; i++ )
{
for ( max = i+1, j = i+2; j < m_size; j++ )
if ( m_Buf[max] < m_Buf[j] ) max = j;
if ( m_Buf[max] > m_Buf[i] ) {
int t = m_Buf[i]; m_Buf[i] = m_Buf[max]; m_Buf[max] = t;
}
}
Show();
}
int Modi()
{
int num=0;
system("cls");
cout << "[1] 배열추가" << endl;
cout << "[2] push_back" << endl;
cout << "[3] pop_back" << endl;
cout << "[4] push_front" << endl;
cout << "[5] pop_front" << endl;
cout << "[6] 배열사이꺼 뺴기 " << endl;
cout << "[7] show " << endl;
cout << "[8] 내림차순정렬" << endl;
cout << "[9] 오름차순정렬" << endl;
cout << "[0] 종 료" << endl;
cin >> num;
return num;
}
void menu()
{
int num=0;
while((num = Modi()) != 0)
{
switch(num)
{
case 1: Add(); break;
case 2:push_back(); break;
case 3:pop_back(); break;
case 4:push_front();break;
case 5:pop_front(); break;
case 6:Pop_Select(); break;
case 7:Show(); break;
case 8 :descending_selection_sort(); break;
case 9:ascending_selection_sort () ;break;
default : cout << "error" << endl;
}
system("PAUSE");
}
}
Array &operator ()(Array &ar)
{
//ar.Show();
return ar;
}
};
template <typename T>
ostream & operator <<(ostream & os, Array<T> &ar)
{
ar.Show();
return os;
}
// 단점
// 1) 정적인 배열의 크기 ==> 동적배열 !!
// 2) 인덱스를 통한 접근이 안됨 ==> 연산자 오버로딩 !!
// 3) 시작위치의 주소값을 같지 않는다 ==> 객체 출력자 구현 !!
void main()
{
Array<int> ar;
cout << ar << endl;
//ar.Show();
//ar.push_back();
}