/*
'보통예금계좌'를 의미하는 NormalAccount 클래스는 객체의 생성과정에서(생성자를 통해서) 이율정보(이자비율의 정보)를 등록할 수 있도록 정의하자.
반면, '신용신뢰계좌'를 의미하는 HighCreditAccount 클래스에는 다음의 특성을 부여해서 정의하자
1.NormalAccount 클래스와 마찬가지로 객체 생성과정에서 기본이율을 등록할 수 있다
2.고객의 신용등급을 A, B, C로 나누고 계좌개설 시 이 정보를 등록한다
3.A, B, C 등급별로 각각 기본이율에 7%, 4%, 2%의 이율을 추가로 제공한다.
사실 이자는 시간이 지나야 발생하지만, 우리는 구현의 편의상 입금시에 이자가 원금에 더해지는 것으로 간주한다.
그리고 모든 계좌에 대해 공히 다음의 조건을 적용하자.
1.계좌개설 과정에서 초기 입금되는 금액에 대해서는 이자를 계산하지 않는다
2.계좌개설 후 별도의 입금과정을 거칠 때에만 이자가 발생하는 것으로 간주한다.
3.이자의 계산과정에서 발생하는 소수점 이하의 금액은 무시한다.
그리고 컨트롤 클래스인 AccountHandler 클래스에는 큰 변화가 없어야 한다.
단, 계좌의 종류가 늘어난 만큼 메뉴의 선택과 데이터의 입력과정에서의 불가피한 변경은 허용한다
*/
#include <iostream>
#include <cstring>
using namespace std;
enum//신용등급
{
RankA=7,
RankB=4,
RankC=2
};
//Entity 클래스
class BankAccount
{
private:
int AccountNumber; //계좌 번호
char *Name; //고객 이름
int Money; //고객의 잔액
public:
BankAccount(int num, char *name, int money);//생성자
BankAccount(const BankAccount ©);//추가된 복사생성자(나름 간단), const 추가
int GetNumber() const;//const 추가
virtual void Deposit(int money); //Entity 클래스에 virtual 추가하는것이 중요(이 부분 때문에 10분 소요...)
int Withdraw(int money);
void ShowAccountInfo() const; //const 추가
~BankAccount(); //소멸자
};
BankAccount::BankAccount(int num, char *name, int money) :AccountNumber(num), Money(money) //생성자
{
Name = new char[strlen(name) + 1];
strcpy(Name, name);
}
BankAccount::BankAccount(const BankAccount ©) :AccountNumber(copy.AccountNumber), Money(copy.Money) //추가된 복사생성자(나름 간단), const 추가
{
Name = new char[strlen(copy.Name) + 1];
strcpy(Name, copy.Name);
}
int BankAccount::GetNumber() const //const 추가
{
return AccountNumber;
}
void BankAccount::Deposit(int money)
{
//printf("%d원이 입금되었습니다\n", money); //제대로 동작하나 확인
Money += money;
}
int BankAccount::Withdraw(int money)
{
if (Money < money)
return 0;
Money -= money;
return money;
}
void BankAccount::ShowAccountInfo() const //const 추가
{
cout << "이름:" << Name << endl;
cout << "계좌번호:" << AccountNumber << endl;
cout << "잔고:" << Money << endl;
}
BankAccount::~BankAccount() //소멸자
{
delete[]Name;
}
//노말
class NormalAccount :public BankAccount
{
private:
int ratio;
public:
NormalAccount(int num, char *name, int money, int profits) :BankAccount(num, name, money), ratio(profits)
{
}
virtual void Deposit(int money)
{
BankAccount::Deposit(money); //원금
BankAccount::Deposit(money*(ratio / 100.0)); //이자
}
};
//신용
class HighCreditAccount :public NormalAccount
{
private:
int credit;
public:
HighCreditAccount(int num, char *name, int money, int profits, int credibility) :NormalAccount(num, name, money, profits), credit(credibility)
{
}
virtual void Deposit(int money)
{
NormalAccount::Deposit(money); //원금 이자
BankAccount::Deposit(money*(credit / 100.0)); //추가이자
}
};
//컨트롤 클래스
class AccountHandler
{
private:
BankAccount *Arr[10]; //계좌 포인터 배열
int AccountNum; //계좌 개수
public:
AccountHandler();
~AccountHandler();
int Menu(void); //메뉴
void MakeBankAccount(void); //계좌 개설
void Deposit(int money); //입금
void Withdraw(int money); //출금
void ShowAccountInfo(void); //전체고객 잔액조회
private: //이 부분은 책을 참고, protected는 외부에서 보면 private, 상속관계에서 보면 public!
void MakeNormalAccount(void);
void MakeCreditAccount(void);
};
AccountHandler::AccountHandler() :AccountNum(0)
{
}
AccountHandler::~AccountHandler()
{
for (int i = 0; i < AccountNum; i++)
delete Arr[i];
}
int AccountHandler::Menu(void)
{
int sel;
cout << "-----Menu-----" << endl;
cout << "1.계좌개설" << endl << "2.입금" << endl << "3.출금" << endl << "4.계좌정보 전체 출력" << endl << "5.프로그램 종료" << endl;
cout << "선택";
cin >> sel;
return sel;
}
void AccountHandler::MakeBankAccount()
{
//이제 계좌 종류가 두가지이므로 이부분은 주석처리
/*
int accountNumber;
char name[30];
int money;
cout << AccountNum + 1 << "번째 사람 정보 입력" << endl;
cout << "계좌번호 입력:";
cin >> accountNumber;
cout << "이름 입력:";
cin >> name;
cout << "잔액 입력:";
cin >> money;
cout << endl;
Arr[AccountNum++] = new BankAccount(accountNumber, name, money); //계좌개설 완료 후 다음 사람으로
*/
int sel;
cout << "계좌 종류를 선택하시오" << endl;
cout << "1.보통계좌\t2.신용계좌:";
cin >> sel;
if (sel == 1)
MakeNormalAccount();
else if (sel == 2)
MakeCreditAccount();
else
{
while (sel == 1 || sel == 2)
{
cout << "번호를 잘못 선택하셨습니다 다시 선택하세요";
cin >> sel;
if (sel == 1)
MakeNormalAccount();
else if (sel == 2)
MakeCreditAccount();
}
}
}
void AccountHandler::MakeNormalAccount(void)
{
int accountNumber;
char name[30];
int money;
int ratio;
cout << AccountNum + 1 << "번째 사람 정보 입력" << endl;
cout << "계좌번호 입력:";
cin >> accountNumber;
cout << "이름 입력:";
cin >> name;
cout << "잔액 입력:";
cin >> money;
cout << "이율 입력:";
cin >> ratio;
cout << endl;
Arr[AccountNum++] = new NormalAccount(accountNumber, name, money, ratio); //계좌개설 완료 후 다음 사람으로
}
void AccountHandler::MakeCreditAccount(void)
{
int accountNumber;
char name[30];
int money;
int ratio;
int rank;
cout << AccountNum + 1 << "번째 사람 정보 입력" << endl;
cout << "계좌번호 입력:";
cin >> accountNumber;
cout << "이름 입력:";
cin >> name;
cout << "잔액 입력:";
cin >> money;
cout << "이율 입력:";
cin >> ratio;
cout << "신용등급(1.RankA, 2.RankB, 3.RankC) 입력:";
cin >> rank;
cout << endl;
switch (rank)
{
case 1:
Arr[AccountNum++] = new HighCreditAccount(accountNumber, name, money, ratio, RankA);
break;
case 2:
Arr[AccountNum++] = new HighCreditAccount(accountNumber, name, money, ratio, RankB);
break;
case 3:
Arr[AccountNum++] = new HighCreditAccount(accountNumber, name, money, ratio, RankC);
break;
}
}
void AccountHandler::Deposit(int money)
{
int number;
cout << "고객님의 계좌번호를 입력해주세요:";
cin >> number;
for (int i = 0; i <= AccountNum; i++)
{
if (Arr[i]->GetNumber() == number) //계좌번호가 같으면
{
Arr[i]->Deposit(money);
cout << "입금이 완료되었습니다" << endl;
return;
}
}
cout << "없는 계좌번호입니다" << endl;
}
void AccountHandler::Withdraw(int money)
{
int number;
cout << "고객님의 계좌번호를 입력해주세요:";
cin >> number;
for (int i = 0; i <= AccountNum; i++)
{
if (Arr[i]->GetNumber() == number) //계좌번호가 같으면
{
if (Arr[i]->Withdraw(money) == 0)
{
cout << "잔액이 부족합니다" << endl;
return;
}
cout << "출금이 완료되었습니다" << endl;
return;
}
}
cout << "없는 계좌번호입니다" << endl;
}
void AccountHandler::ShowAccountInfo(void)
{
for (int i = 0; i < AccountNum; i++)
{
Arr[i]->ShowAccountInfo();
cout << endl;
}
}
int main(void)
{
AccountHandler handler;
int money;
while (1)
{
int sel = handler.Menu();
switch (sel)
{
case 1:
handler.MakeBankAccount();
break;
case 2:
cout << "입금할 금액:";
cin >> money;
handler.Deposit(money);
break;
case 3:
cout << "출금할 금액:";
cin >> money;
handler.Withdraw(money);
break;
case 4:
handler.ShowAccountInfo();
break;
case 5:
return 0;
default:
cout << "잘못된 번호를 입력하셨습니다" << endl;
}
}
return 0;
}
개발 환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
[참고] 열혈 C++ 프로그래밍 윤성우 저
'C++ > 열혈 C++ 프로그래밍(윤성우 저)' 카테고리의 다른 글
열혈 C++ 프로그래밍 10-1 문제 (0) | 2017.06.08 |
---|---|
OOP 단계별 프로젝트 7 (0) | 2017.06.08 |
열혈 C++ 프로그래밍 8-1 문제 (0) | 2017.06.06 |
OOP 단계별 프로젝트 5 (0) | 2017.06.05 |
열혈 C++ 프로그래밍 7-2 문제 (0) | 2017.06.05 |