기존 배열클래스(account array class)를 클래스 템플릿으로 재 정의 하여 다양한 반환형으로 배열객체에 접근할 수 있도록 한다.
배열객체에 접근하고자 할 때 주소값으로 접근하는 것이 보편적이나 상황에 따라 객체 복사값만을 요구로 할 수 있기 때문에 형(type)의 유동성을 고려, 클래스 템플릿으로 재정의 하고자 한다. 또한 기존의 arrayclass에 각각 다른 반환형을 얻고자 정의했던 두 개의 다른 '[]'연산자 오버로드 함수를 하나로 통합하여 클래스의 간결성 또한 얻어낼 수 있다.
각 7개의 header file, source file을 모두 적시하진 않겠다. 변경사항이 있는
accountarray.h
accountarray.cpp
accounthandler.h
의 코드만 리뷰, 분석해 보도록 하겠다.
accountarray.h
#include "account.h"
#include <iostream>
#pragma once
using namespace std;
/*클래스 템플릿*/
template <typename T>
class Accountarray
{
private:
T * arr;
// 복사생성자, 대입연산자 방지
int len;
Accountarray(Accountarray& Acopy);
Accountarray& operator=(Accountarray& Acopy);
public:
// 생성자 - 동적할당
Accountarray();
// []연산자 오버로드 함수, 하나로 통합! - 반환형을 자유롭게
T& operator[](int idx);
int Getlen();
// 소멸자
~Accountarray();
};
accountarray.cpp
#include "string.h"
#include "accountarray.h"
#include <cstdlib> // exit function
#include "account.h"
// 클래스 템플릿 정의
/* template 선언 이후에..
1. 해당 클래스 템플릿 함수가 임의 형(type)를 필요로 하면 template <typename T>
2. 해당 클래스 템플릿 함수가 임의 형을 필요로 하지 않는 함수라면 template<>
으로 선언한다
*/
// 생성자
template <typename T>
Accountarray<T>::Accountarray()
:len(100)
{
arr = new T[100]; // 배열 동적할당, 임의형 T는 사용자로부터 입력되어야 하는 값
}
// []연산자 오버로드 함수
template <typename T>
T& Accountarray<T>::operator[](int idx)
{
// out of range
if (idx < 0 || idx >= len)
{
cout << "out of range" << endl;
exit(1);
}
// 배열의 idx번째 인자를 임시 T&형으로 반환한다.
return arr[idx];
}
// 소멸자
template <> // 함수 내에서 typename T가 필요하지 않은 경우
Accountarray<T>::~Accountarray()
{
delete []arr;
}
accounthandler.h
#include "accountarray.h"
#include "account.h"
#pragma once
/*Controller class*/
class Accounthandler
{
private:
Accountarray<ACCOUNT_PTR> acc;
// Account의 포인터형인 ACCOUNT_PTR을 typename 'T'값으로 한 Accountarray 객체 acc를 생성
int acc_count; // 고객번호
public:
// 생성자
Accounthandler();
// 기능함수(메뉴, 생성, 입금, 출금, 조회)
void Menu();
void Make();
void Deposit();
void Withdraw();
void Show();
};
결과는 ver.5와 같아 첨부하지 않고, 대신 헤더파일, 소스파일이 저장돼 있는 전체적인 모습을 보여드리자면..
배열클래스를 클래스 템플릿으로 재정의하여 하나의 정의를 이용해 다양한 형의 템플릿 클래스를 호출(가상생성)할 수 있다. 단, 이 프로젝트에선 크게 의미가 없을 듯 하며 방지차원이라 볼 수 있다.