#pragma once
// 고객 등급별(NORMAL, HIGH) 상이한 이자율을 적용하기 위해 이름공간 "TYPE"에 문자 열거(enum)
namespace TYPE
{
enum
{
NORMAL = 1, HIGH
};
}
// 옵션에 해당하는 문자들에 정수의미 부여
enum
{
MAKE = 1, DEPOSIT, WITHDRAW, SHOW, EXIT
};
// 고객명, 계좌번호 배열 길이에 일관성을 두기위해 전역변수 생성.
const int NAME_LEN = 30;
const int ID_LEN = 30;
/***Account class**
Account 클래스는
1. 실제 객체생성을 할 필요가 없는 명목 클래스
2. Normal, High 클래스의 기초 클래스
3. Entity 클래스
이다.
*/
class Account
{
private:
char* acc_id; // 계좌번호
char* acc_name; // 성명
double acc_balance; // 잔금
// 생성자, 복사생성자, 소멸자 선언
/*명목클래스인데도 생성자, 복사생성자를 생성하는 이유
: Account 클래스를 상속할 유도클래스 들의 생성자, 복사생성자가 참조할 수 있게 하기 위해
*/
public:
Account(const char* acc_id, const char* acc_name, double acc_seed);
Account(Account& copy);
~Account();
// 기타 재료함수 선언
// 계좌번호 반환
char* Get_id();
// 잔금 반환
double Get_balance();
/* virtual!!
추후 오버라이딩될 Proccess_depos(입금함수)를 이에 접근하는 객체 클래스에 맞춰
호출할 수 있도록 보장해주는 장치
*/
// 입금함수
virtual void Proccess_depos(double money);
// 출금함수
void Proccess_withdraw(double money);
// 조회함수
void Showinform();
};
/*Accounthandler class*/
class Accounthandler // controller or handler 클래스로서 기능적인 역할을 수행한다.
{
private:
Account* acc[100]; // 길이가 100인 Account 배열 객체 선언
int acc_count; // 고객 고유번호
public:
// 생성자, 소멸자 (**백업**을 위해선 **복사생성자** 또한 선언해야 하지만 배제함을 가정하겠음)
Accounthandler();
~Accounthandler();
// 기능함수 선언(메뉴, 개설, 입금, 출금, 조회)
void Menu();
void Make();
void Deposit();
void Withdraw();
void Show();
};
/*Normal class*/
class Normal : public Account // Account 클래스를 상속받는 유도클래스
{
private:
double acc_rate; // 일반 이자율
public:
// 생성자
Normal(const char* id, const char* name, double seed, double rate);
// 입금함수 오버라이딩1
void Proccess_depos(double money);
// 이자율 반환
double Getrate();
};
class High : public Normal // Account 클래스의 하위클래스인 Normal클래스를 상속받는 High클래스
{
private:
// 고객 등급에 따라 특별이자율을 결정
char acc_type; // 고객등급
double acc_srate; // 특별이자율
public:
High(char* id, char* name, double seed, double rate, char type);
// 입금함수 오버라이딩2
void Proccess_depos(double money);
};
#include "account.h" // 헤더파일 참조
#include<iostream>
#include<cstring> // for the use of strcpy, strcmp
using namespace std;
/*Account class*/
/*생성자*/
Account::Account(const char* Acc_id, const char* Acc_name, double acc_seed)
:acc_balance(acc_seed)
{
// 동적할당
int len1 = strlen(Acc_id) + 1;
int len2 = strlen(Acc_name) + 1;
acc_id = new char[len1];
acc_name = new char[len2];
strcpy(acc_id, Acc_id);
strcpy(acc_name, Acc_name);
}
/*복사생성자*/
Account::Account(Account& copy)
{
int len1, len2;
len1 = strlen(copy.acc_id) + 1;
len2 = strlen(copy.acc_name) + 1;
acc_id = new char[len1];
acc_name = new char[len2];
strcpy(acc_id, copy.acc_id);
strcpy(acc_name, copy.acc_name);
}
/*소멸자*/
Account::~Account()
{
delete[]acc_id;
delete[]acc_name;
}
/*기타 함수*/
// 계좌 반환
char *Account::Get_id()
{
return acc_id;
}
// 잔금 반환(소수자리 표현)
double Account::Get_balance()
{
return acc_balance;
}
/*입금함수*/
/* 굳이 별도 정의를 내리지 않고, 순수 가상함수로 만들어 클래스 자체를
가상클래스화 하는 것이 바람직하나 아직 적용하지 않겠음 */
void Account::Proccess_depos(double money)
{
acc_balance += money;
}
// 출금함수
void Account::Proccess_withdraw(double money)
{
acc_balance -= money;
}
// 조회함수
void Account::Showinform()
{
cout << "계좌번호 : " << acc_id << endl;
cout << "고객이름 : " << acc_name << endl;
cout << "잔액 : " << acc_balance;
}
--------------------------------------------------------------------------------------
/*Normal class*/
// 생성자
Normal::Normal(const char* Acc_id, const char* Acc_name, double acc_seed, double rate)
: acc_rate(rate), Account(Acc_id, Acc_name, acc_seed) // 기초클래스의 생성자 참조(호출)
{
}
// 입금함수(일반 이자율 고려)
void Normal::Proccess_depos(double money) // virtual을 추가 선언할 필요는 없다. 생략가능
{
// **총 입금액 = 원 입금액 + 원금*일반이자율**
Account::Proccess_depos(money+Account::Get_balance()*acc_rate) ;
}
// 이자율 반환
double Normal::Getrate()
{
return acc_rate;
}
--------------------------------------------------------------------------------------
/*High class*/
// 생성자
High::High(char* id, char* name, double seed, double rate, char type)
: Normal(id, name, seed, rate) // 기초클래스인 Normal 클래스의 생성자 참조(호출)
{
// 등급(char type 매개변수를 통해 복사된 인자값)에 따른 특별이자율 초기화
switch(type)
{
case 'A':
{
acc_srate = 0.07;
break;
}
case 'B':
{
acc_srate = 0.04;
break;
}
case 'C':
{
acc_srate = 0.02;
break;
}
default:
{
cout << "유형을 재입력 하세요" << endl;
}
}
}
// 입금함수. 일반이자율 & 특별이자율 고려
void High::Proccess_depos(double money)
{
// 총 입금액 = 원 입금액 + 원금*(일반이율 + 특별이율)
Account::Proccess_depos(money+ Get_balance()*(Getrate()+acc_srate));
}
---------------------------------------------------------------------------------------
/*Accounthandler class*/
// 생성자
Accounthandler::Accounthandler()
:acc_count(0) // 0부터 고객번호 시작
{
}
// 소멸자
// 동적할당으로 생성될 객체배열 인자 acc[i]를 소멸
Accounthandler::~Accounthandler()
{
for (int i = 0; i < acc_count; i++)
{
delete acc[i]; // 동적할당 소멸
}
}
// 기능 함수 정의
// 메뉴창
void Accounthandler::Menu()
{
cout << "-------------------------------------------------" << endl;
cout << "가능 업무" << endl;
cout << "1. 계좌 생성 "<< endl;
cout << "2. 입금" << endl;
cout << "3. 출금" << endl;
cout << "4. 조회" << endl;
cout << "5. 프로그램 종료" << endl;
}
// 개설
void Accounthandler::Make()
{
char acc_id[ID_LEN];
char acc_name[NAME_LEN];
int acc_balance;
int type;
cout << "계좌번호 : "; cin >> acc_id;
cout << "성명 : "; cin >> acc_name;
cout << "예치금 : "; cin >> acc_balance;
cout << "[계좌유형 결정]" << endl;
cout << "(Normal=1/High=2) : " ; cin >> type; // 계좌 유형에 따라..
double rate;
char acc_level;
// 계좌 생성 방법이 다르다(서로 다른 타입의 동적할당)
switch(type)
{
// 일반등급 계좌, 일반이율만 기입하며 Normal 클래스형으로 동적할당함
case TYPE::NORMAL:
{
cout << "이율 : " ; cin >> rate; // 일반이율 입력
// Account 객체배열인자 동적할당(i=0 ~ )
acc[acc_count++] = new Normal(acc_id, acc_name, acc_balance, rate);
break;
}
case TYPE::HIGH: // 일반이율, 고객등급을 모두 적시해야 하며 High클래스형으로 동적할당
{
cout << "이율 : " ; cin >> rate; // 일반이율
cout << "고객등급 : " ; cin >> acc_level; // 고객등급 적시
// 동적할당
acc[acc_count++] = new High(acc_id, acc_name, acc_balance, rate, acc_level);
}
}
}
// 입금함수(virtual, overriding)
void Accounthandler::Deposit()
{
// 입금관련 고객정보 입력
char id[ID_LEN];
int money;
cout << "계좌번호 입력 : "; cin >> id; // 계좌번호 입력
for (int i = 0; i < acc_count; i++)
{
if (strcmp(acc[i]-> Get_id(), id) ==0) // 계좌번호 반환함수 호출, 일치 확인
{
cout << "금액(만원) : "; cin >> money; // 입금액 입력
/*
Proccess_depos 함수는 virtual선언이 된 가상함수이다. 따라서 등급별(Normal / High)로 다르게
동적할당된 객체배열인자 acc[i]들 각각의 클래스에 해당하는 함수를 호출하게 된다
*/
acc[i] -> Proccess_depos(money);
cout << "정상 입금 되었습니다." << endl;
break;
}
else if(i==acc_count - 1) // 계좌번호 불일치 시
cout << "계좌번호가 정확히 입력되었는지 확인하세요" << endl;
}
}
// 출금함수
void Accounthandler::Withdraw()
{
// 거래관련 정보 입력
char id[ID_LEN];
int money;
cout << "계좌번호 입력 : "; cin >> id; // 계좌번호 입력
for (int i = 0; i < acc_count; i++)
{
if (strcmp(acc[i]-> Get_id(), id) ==0) // 계좌번호 일치 확인
{
cout << "금액(만원) : "; cin >> money; // 출금액 입력
// 출금함수는 계좌유형에 상관없이 **동일기능**을 요구하기 때문에 virtual선언하지 않는다.
acc[i] -> Proccess_withdraw(money);
cout << "정상 출금 되었습니다." << endl;
}
else if(i == acc_count - 1) // 불일치 시
cout << "계좌번호가 정확히 입력되었는지 확인하세요" << endl;
}
}
// 조회함수
void Accounthandler::Show()
{
cout << "------------------" ;
for (int i = 0; i < acc_count; i++)
{
cout << endl << "[" << i << "번째 고객 정보]" << endl;
acc[i]->Showinform(); // Account의 조회함수 호출
cout << " 만원" << endl << endl;
}
}
#include "account.h"
#include <iostream>
#include<cstring>
using namespace std; // for the use of strcmp
int main()
{
Accounthandler AH; // Accounthandler 클래스 객체를 생성해 멤버함수에 접근
int choice;
while (1)
{
AH.Menu(); // 메뉴창
cout << "거래를 선택하세요 : "; cin >> choice; // 거래유형 선택
switch (choice)
{
case MAKE: // 생성
{
AH.Make();
break;
}
case DEPOSIT: // 입금
{
AH.Deposit();
break;
}
case WITHDRAW: // 출금
{
AH.Withdraw();
break;
}
case SHOW: // 조회
{
AH.Show();
break;
}
case EXIT: // 종료
{
cout << "거래를 종료합니다." << endl;
return 0;
}
default: // 옵션에 벗어난값 입력 시
{
cout << "다른 옵션을 선택하세요" << endl;
}
}
char further[5];
cout << "거래를 계속 하시겠습니까?(yes / no) : "; cin >> further;
if (strcmp(further, "no") == 0)
{
return 0;
}
}
return 0;
}
상속의 사용으로 하나의 공유(가상, 부모, 기초)클래스를 두고 여러 성격이 다른 유도클래스를 정의하여 활용할 수 있다.