2024. 4. 16. 17:47ㆍ[C++]/C++ 언어 기초
상속의 목적이 명확하지 않다면, 상속은 하지 않는 편이 나을 수도 있다. 그런데 우리는 앞서 상속이 필요한 가장 대표적이고도 중요한 이유를 확인하였다. 그리고 그 때 얻게 되는 이점이 무엇인지도 확인하였다.
프로젝트 06단계의 도입
본 단계의 프로젝트에서는 이전에 정의한 Account 클래스를 상속하는 다음 두 클래스를 추가로 정의하고자 한다.
- NormalAccount 보통예금계좌
- HighCreditAccount 신용신뢰계좌
앞서 정의한 Account 클래스는 이자와 관련된 내용이 없다. (실제 이자가 지급되지 않는 계좌도 있다.) 그런데 일반 사용자가 이용하는 예금에는 적게나마 이자가 지급이 되니, 이자의 지급 및 처리방식에 따라서 위의 두 클래스를 추가로 정의하고자 한다위에서 말하는 '보통예금계좌' 는 우리가 흔히 사용하는, 최소한의 이자를 지급하는 자율 입출금식 계좌이다.반면 '신용신뢰계좌' 는 신용도가 높은 고객에게만 개설을 허용하는 높은 이율의 계좌를 의미한다.
프로그램 설명
'보통예금계좌'를 의미하는 NormalAccount 클래스는 객체의 생성과정에서(생성자를 통해서) 이율정보(이자비율의 정보)를 등록할 수 있도록 정의하자. 반면, '신용신뢰계좌'를 의미하는 HighCreditAccount 클래스에는 다음의 특성을 부여해서 정의하자
- NormalAccount 클래스와 마찬가지로 객체 생성과정에서 기본이율을 등록할 수 있다
- 고객의 신용등급을 A, B, C로 나누고 계좌개설 시 이 정보를 등록한다
- A, B, C 등급별로 각각 기본이율에 7%, 4%, 2%의 이율을 추가로 제공한다.
사실 이자는 시간이 지나야 발생하지만, 우리는 구현의 편의상 입금시에 이자가 원금에 더해지는 것으로 간주한다. 그리고 모든 계좌에 대해 공히 다음의 조건을 적용하자.
- 계좌개설 과정에서 초기 입금되는 금액에 대해서는 이자를 계산하지 않는다
- 계좌개설 후 별도의 입금과정을 거칠 때에만 이자가 발생하는 것으로 간주한다.
- 이자의 계산과정에서 발생하는 소수점 이하의 금액은 무시한다.
그리고 컨트롤 클래스인 AccountHandler 클래스에는 큰 변화가 없어야 한다. 단, 계좌의 종류가 늘어난 만큼 메뉴의 선택과 데이터의 입력과정에서의 불가피한 변경은 허용한다.
실행의 예
계좌의 개설과정 1
-----Menu-----
1. 계좌개설
2. 입금
3. 출금
4. 계좌번호 전체 출력
5. 프로그램 종료
선택: 1
[계좌종류선택]
1. 보통예금계좌 2. 신용신뢰계좌
선택 : 1
[보통예금계좌 개설]
계좌ID: 123
이름: LeeHong
입금액: 0
이자율: 3
계좌의 개설과정 2
-----Menu-----
1. 계좌개설
2. 입금
3. 출금
4. 계좌번호 전체 출력
5. 프로그램 종료
선택: 1
[계좌종류선택]
1. 보통예금계좌 2. 신용신뢰계좌
선택 : 2
[신용신뢰계좌 개설]
계좌ID: 7272
이름: ParkJun
입금액: 10000
이자율: 9
신용등급(1toA, 2toB, 3toC): 2
내 코드
#include "stdafx.h"
#include <iostream>
#include <cstring>
using namespace std;
/* enum */
//선택 메뉴
enum {Make = 1, Deposit, Withdraw, ShowAcc, EXIT};
//계좌 종류
enum {Normal = 1, Credit = 2};
//신용등급
enum{LEVEL_A = 7, LEVEL_B = 4, LEVEL_C = 2};
//Acounts Entity Class
class Accounts{
private:
int accId;
int money;
char *cusName;
public:
Accounts(int Id, int mymoney, char *name);
Accounts(const Accounts ©);
virtual void Deposit(int mymoney);
int Withdraw(int mymoney);
void ShowAccInfo() const;
int GetAccId() const;
char* GetCusName() const;
int GetMoney() const;
~Accounts();
};
Accounts::Accounts(int ID, int money, char *name):accId(ID), money(money){
cusName = new char[strlen(name)+1];
strcpy_s(cusName,strlen(name)+1, name);
}
Accounts::Accounts(const Accounts ©){
cusName = new char[strlen(copy.cusName)+1];
strcpy_s(cusName, strlen(copy.cusName)+1, copy.cusName);
}
void Accounts::Deposit(int mymoney){money+=mymoney;}
int Accounts::Withdraw(int mymoney){
if(money < mymoney){
cout<<"계좌에 잔액이 부족합니다."<<endl;
return 0;
}
money -= mymoney;
return mymoney;
}
void Accounts::ShowAccInfo() const {
cout<<"계좌Id: "<<accId<<endl;
cout<<"이름: "<<cusName<<endl;
cout<<"잔액: "<<money<<endl<<endl;
}
int Accounts::GetAccId() const{return accId;}
char* Accounts::GetCusName() const {return cusName;}
int Accounts::GetMoney() const {return money;}
Accounts::~Accounts(){
delete []cusName;
}
/*Normal Account Class : Account Class 상속*/
class NormalAccount : public Accounts{
private:
int rate;
public:
NormalAccount(int accId, int money, char *cusName, int ratio):Accounts(accId, money, cusName), rate(ratio){}
virtual void Deposit(int money){
Accounts::Deposit(money);
Accounts::Deposit(money*(rate/100.0));
}
};
//이쪽 부분 수정 요망
/*HighCredit Account Class : Account Class 상속*/
class HighCreditAccount : public NormalAccount{
private:
int creditrank;
public:
HighCreditAccount(int accId, int money, char *cusName, int ratio, int ranks):NormalAccount(accId, money, cusName, ratio), creditrank(ranks){}
virtual void Deposit(int money){
//입금할 때, 기본급 + 기본 이자 + 등급 추가 이자(A = 7%, B = 4%, C = 2%)
NormalAccount::Deposit(money);
Accounts::Deposit(money*(creditrank/100.0));
}
};
/*Acounts Control Class*/
class AccountsHandler{
private:
Accounts *accArr[100];
int accNum;
public:
AccountsHandler();
void ShowMenu(void) const;
void MakeAcc(void);
void DepositMoney(void);
void WithdrawMoney(void);
void ShowAllAccInfo(void);
~AccountsHandler();
protected:
void MakeNormalAcc(void);
void MakeCreditAcc(void);
};
AccountsHandler::AccountsHandler():accNum(0){}
void AccountsHandler::ShowMenu(void) const{
cout<<"-------Menu-------"<<endl<<"1. 계좌개설"<<endl<<"2. 입 금"<<endl<<"3. 출 금"<<endl<<"4. 계좌정보 전체 출력"<<endl<<"5. 프로그램 종료"<<endl;
}
void AccountsHandler::MakeAcc(void){
int acc;
cout<<"[계좌종류선택]"<<endl<<"1. 보통예금계좌 "<<"2. 신용신뢰계좌"<<endl;
cout<<"선택: ";cin>>acc;
if(acc == Normal)
MakeNormalAcc();
else
MakeCreditAcc();
}
void AccountsHandler::MakeNormalAcc(void){
int id, money, rate;
char name[20];
cout<<"[보통예금계좌 개설]"<<endl;
cout<<"계좌ID: ";
while (!(cin >> id)) {
cin.clear();
cin.ignore(INT_MAX,'\n');
cout << "잘못된 값을 입력하셨습니다. 정수로 입력해주세요 \n";
cout <<"계좌 ID: ";
}
cout<<"이름(최대 20자): "; cin>>name;
cout<<"입금액: "; cin>>money;
cout<<"이자율: "; cin>>rate;
cout<<endl;
accArr[accNum++] = new NormalAccount(id, money, name, rate);
}
void AccountsHandler::MakeCreditAcc(void){
int id, money, rate, ranks;
char name[20];
cout<<"[신용신뢰계좌 개설]"<<endl;
cout<<"계좌ID: ";
while (!(cin >> id)) {
cin.clear();
cin.ignore(INT_MAX,'\n');
cout << "잘못된 값을 입력하셨습니다. 정수로 입력해주세요 \n";
cout <<"계좌 ID: ";
}
cout<<"이름(최대 20자): "; cin>>name;
cout<<"입금액: "; cin>>money;
cout<<"이자율: "; cin>>rate;
cout<<"신용등급(1toA, 2toB, 3toC): "; cin>>ranks;
cout<<endl;
switch(ranks){
case 1:
accArr[accNum++] = new HighCreditAccount(id, money, name, rate, LEVEL_A);
break;
case 2:
accArr[accNum++] = new HighCreditAccount(id, money, name, rate, LEVEL_B);
break;
case 3:
accArr[accNum++] = new HighCreditAccount(id, money, name, rate, LEVEL_C);
break;
}
}
void AccountsHandler::DepositMoney(void){
int id, money;
cout<<"[입 금]"<<endl;
cout<<"계좌ID: ";
while (!(cin >> id)) {
cin.clear();
cin.ignore(INT_MAX,'\n');
cout << "잘못된 값을 입력하셨습니다. 정수로 입력해주세요 \n";
cout <<"계좌 ID: ";
}
cout<<"입금액: ";cin>>money;
for(int i = 0; i<accNum; i++){
if(accArr[i] -> GetAccId() == id){
accArr[i] -> Deposit(money);
cout<<"입금완료"<<endl;
cout<<accArr[i]->GetCusName()<<"고객님의 입금 후 잔액 : "<<accArr[i]->GetMoney()<<endl;
return;
}
}
cout<<"아이디가 없습니다."<<endl;
}
void AccountsHandler::WithdrawMoney(void){
int id, money;
cout<<"[출 금]"<<endl;
cout<<"계좌ID: ";
while (!(cin >> id)) {
cin.clear();
cin.ignore(INT_MAX,'\n');
cout << "잘못된 값을 입력하셨습니다. 정수로 입력해주세요."<<endl;
cout <<"계좌 ID: ";
}
cout<<"출금액: ";
while (!(cin >> money)) {
cin.clear();
cin.ignore(INT_MAX,'\n');
cout << "잘못된 값을 입력하셨습니다."<<endl;
cout <<"출금액: ";
}
for(int i = 0; i<accNum; i++){
if(accArr[i] -> GetAccId() == id){
if(accArr[i] ->Withdraw(money) == 0){
cout<<"잔액부족"<<endl<<endl;
return ;
}
cout<<"출금완료"<<endl;
cout<<accArr[i]->GetCusName()<<"고객님의 출금 후 잔액 : "<<accArr[i]->GetMoney()<<endl;
return;
}
}
cout<<"아이디가 없습니다."<<endl;
}
//계좌정보 전체 출력
void AccountsHandler::ShowAllAccInfo(void){
for(int i = 0; i<accNum;i++){
cout<<"["<<i+1<<"번째 계좌정보]"<<endl;
accArr[i] -> ShowAccInfo();
if(i+1 == accNum){
cout<<"-------전체 계좌 출력 완료-------"<<endl<<endl;
}
}
}
AccountsHandler::~AccountsHandler(){
for(int i = 0; i<accNum; i++){
delete accArr[i];
}
}
int main(void)
{
AccountsHandler manager;
int select;
while(1){
manager.ShowMenu();
cout<<"번호를 입력하세요. : ";cin>>select;
cout<<endl;
switch(select){
case Make:
manager.MakeAcc();
break;
case Deposit:
manager.DepositMoney();
break;
case Withdraw:
manager.WithdrawMoney();
break;
case ShowAcc:
manager.ShowAllAccInfo();
break;
case EXIT:
return 0;
default:
cout<<"유효하지 않은 번호입니다."<<endl<<endl;
}
}
return 0;
}
기존 코드
01 단계 코드
https://kjy1ho.tistory.com/337
01-06 은행계좌프로그램 실습 1단계
프로그램 설명 우리가 구현하고자 하는것은 "은행계좌 관리 프로그램"이다. 1단계에서는 C스타일로 구현하는 것을 목표로 한다. 구현할 기능은 다음과 같다. 기능 1. 계좌개설 기능 2. 입 금 기능
kjy1ho.tistory.com
02단계 코드
https://kjy1ho.tistory.com/351
04-05 은행계좌문제 2단계
프로젝트 02단계 도입 이제 클래스에 대한 기본적인 내용들을 공부하였다. 이젠 문법적요소에 신경쓰기보다는 무엇을 클래스로 만들 것이며 어떻게 클래스를 정의할 것인가에 더 신경을 써야
kjy1ho.tistory.com
03단계 코드
https://kjy1ho.tistory.com/355
은행계좌프로그램 실습 3단계
프로젝트 03단계의 도입 깊은 복사를 원칙으로 한다면, 클래스의 생성자만 봐도 복사 생성자의 필요성을 판단할 수 있다. 실제 복사 생성자의 호출 여부는 중요하지 않다. 클래스는 그 자체로 완
kjy1ho.tistory.com
4단계 코드
https://kjy1ho.tistory.com/359
은행계좌프로그램 실습 4단계
프로젝트 04 단계의 도입 여러 Chapter를 통해서 const에 대해 설명하였으니, 우리가 진행하는 프로젝트에도 const 선언을 추가해서 코드의 안전성을 높여보겠다. 프로그램 설명 Account 클래스의 멤버
kjy1ho.tistory.com
5단계 코드
https://kjy1ho.tistory.com/manage/newpost/364?returnURL=https%3A%2F%2Fkjy1ho.tistory.com%2F364&type=post
kjy1ho.tistory.com
'[C++] > C++ 언어 기초' 카테고리의 다른 글
32. [C++] 예외처리 (0) | 2024.04.25 |
---|---|
31. [C++] 템플릿 (0) | 2024.04.24 |
30. [C++] 가상 소멸자와 참조자의 참조 가능성 (0) | 2024.04.16 |
29. [C++] 가상 함수(Virtual Function) (0) | 2024.04.16 |
28. [C++] 객체 포인터의 참조 관계 (0) | 2024.04.16 |