C++/열혈 C++ 프로그래밍(윤성우 저)

OOP 단계별 프로젝트 8

꾸준함. 2017. 6. 12. 22:20

[Account.h]

/*

Account 클래스는 깊은 복사를 진행하도록 복사 생성자가 정의되어 있다. 따라서 대입 연산자도 깊은 복사가 진행되도록 정의하는 것이 좋다.

그리고 AccountHandler 클래스에는 배열이 멤버로 선언되어서 객체의 저장을 주도 하는데,

이를 이번 Chapter에서 정의한 BoundCheckPointPtrArray 배열 클래스로 대체하고자 한다.

물론, 이를 위해서는 약간의 수정이 필요하며, 클래스의 이름도 적당히 변경해야할 필요가 있다.

 

실제 변경이 발생하는 헤더파일과 소스파일은 다음과 같다

 

Account.h Account.cpp-> 대입 연산자의 정의

AccountHandler.h-> BoundCheckPointPtrArray 클래스의 적용

 

따라서 이들 파일에 대한 버전정보를 갱신하기 바란다.

또한, 배열 클래스의 추가를 위해서 다음의 소스파일과 헤더파일을 추가하기로 하자.

 

AccountArray.h, AccountArray.cpp->배열 클래스의 선언과 정의

 

, 위에서 언급한 파일과 BankingCommonDecl.h를 제외한 다른 파일에서 수정이 발생했다면,

무엇인가 잘못되었거나 불필요한 수정이 가해졌을 수도 있으니 다시 한번 확인하기 바란다.

*/

 

#ifndef __ACCOUNT_H__

#define __ACCOUNT_H__

 

//Entity 클래스

class BankAccount

{

private:

        int AccountNumber; //계좌 번호

        char *Name; //고객 이름

        int Money; //고객의 잔액

public:

        BankAccount(int num, char *name, int money);

        BankAccount(const BankAccount &copy);

        BankAccount &operator=(const BankAccount &ref); //추가된 문장

 

        int GetNumber() const;

        virtual void Deposit(int money);

        int Withdraw(int money);

        void ShowAccountInfo() const;

        ~BankAccount();

};

 

#endif

 

[Account.cpp]

#include "BankingCommonDecl.h"

#include "Account.h"

 

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 &copy) :AccountNumber(copy.AccountNumber), Money(copy.Money)

{

        Name = new char[strlen(copy.Name) + 1];

        strcpy(Name, copy.Name);

}

 

BankAccount &BankAccount::operator=(const BankAccount &ref) //이번에 추가

{

        AccountNumber = ref.AccountNumber;

        Money = ref.Money;

 

        delete[]Name; //메모리 누수 방지

        Name = new char[strlen(ref.Name) + 1];

        strcpy(Name, ref.Name);

        return *this;

}

 

int BankAccount::GetNumber() 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

{

        cout << "이름:" << Name << endl;

        cout << "계좌번호:" << AccountNumber << endl;

        cout << "잔고:" << Money << endl;

}

 

BankAccount::~BankAccount()

{

        delete[]Name;

}


[AccountArray.h]

#ifndef __ACCOUNT_ARRAY_H__

#define __ACCOUNT_ARRAY_H__

 

#include "Account.h"

typedef BankAccount *BANKACCOUNT_PTR; //포인터 typedef

 

class BoundCheckAccountPtrArray

{

private:

        BoundCheckAccountPtrArray &operator=(const BoundCheckAccountPtrArray &arr) //복사 원천적으로 막음

        {

        }

public:

        BoundCheckAccountPtrArray(int len = 100);

        BANKACCOUNT_PTR *arr;

        int arrlen;

        BoundCheckAccountPtrArray(const BoundCheckAccountPtrArray &arr) //대입 원천적으로 막음

        {

        }

        BANKACCOUNT_PTR &operator[](int idx);

        BANKACCOUNT_PTR operator[](int idx) const; //const 대상의 오버로딩

        int GetArrLen() const;

        ~BoundCheckAccountPtrArray();

};

 

#endif

 

[AccountArray.cpp]

#include "BankingCommonDecl.h"

#include "AccountArray.h"

 

BoundCheckAccountPtrArray::BoundCheckAccountPtrArray(int len) :arrlen(len)

{

        arr = new BANKACCOUNT_PTR[len];

}

 

BANKACCOUNT_PTR &BoundCheckAccountPtrArray::operator[](int idx)

{

        if (idx < 0 || idx >= arrlen)

        {

               cout << "Array index out of bound exception" << endl;

               exit(1);

        }

        return arr[idx];

}

 

BANKACCOUNT_PTR BoundCheckAccountPtrArray::operator[](int idx) const

{

        if (idx < 0 || idx >= arrlen)

        {

               cout << "Array index out of bound exception" << endl;

               exit(1);

        }

        return arr[idx];

}

 

int BoundCheckAccountPtrArray::GetArrLen() const

{

        return arrlen;

}

 

BoundCheckAccountPtrArray::~BoundCheckAccountPtrArray()

{

        delete[]arr;

}


[NormalAccount.h]

#ifndef __NORMAL_ACCOUNT_H__

#define __NORMAL_ACCOUNT_H__

 

#include "Account.h"

 

//노말

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)); //이자

        }

};

 

#endif


[HighCreditAccount.h]

#ifndef __HIGHCREDIT_ACCOUNT_H__

#define __HIGHCREDIT_ACCOUNT_H__

 

#include "NormalAccount.h"

 

//신용

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)); //추가이자

        }

};

 

#endif


[AccountHandler.h]

#ifndef __ACCOUNT_HANDLER_H__

#define __ACCOUNT_HANDLER_H__

 

#include "Account.h"

#include "AccountArray.h"

 

//컨트롤 클래스

class AccountHandler

{

private:

        /*

        BankAccount *Arr[10]; //계좌 포인터 배열

        */

        BoundCheckAccountPtrArray Arr; //이번에 추가

        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);

};

 

#endif

[AccountHandler.cpp]

#include "BankingCommonDecl.h"

#include "AccountHandler.h"

#include "Account.h"

#include "NormalAccount.h"

#include "HighCreditAccount.h"

 

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 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;

        }

}


[BankingSystemMain.cpp]

#include "BankingCommonDecl.h"

#include "AccountHandler.h"

 

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++ 프로그래밍 윤성우 저



반응형