[C++]OOP 단계별 프로젝트 02단계

서희찬·2021년 5월 19일
post-thumbnail

프로젝트 02단계 도입

이제 클래스에 대한 기본적인 내용들을 공부하였다.
이젠 문법적요소에 신경쓰기보다는 무엇을 클래스로 만들 것이며 어떻게 클래스를 정의할 것인가에 더 신경을 써야 한다!
C++는 문법의 80프로 만 이해하고 있어도 실무 프로젝트에 무리 없이 진행 할 수 있다.
그러나!
클래스를 제대로 만들어 내지 못한다면 아무리 문법을 100프로 이해하고 있어도 프로젝트의 진행 자체가 불가능해진다 !

프로그램 설명

뱅킹시스템 1단계를 2단계로 업그레이드 시켜보자 .
1단계에서 정의한 구조체 Account를 클래스 Account로 변경해보자.

이는 키워드 struct를 class로 변경하라는 뜻이 아니다.

다음과 같은 내용들을 더불어 고민하라는 뜻이다.

"어떻게 캡슐화를 시키고 정보 은닉시켜야 할까?"
"생성자와 소멸자는 어떻게 정의해야 할까?"

버전 1에서의 Account 구조체는 char형 배열을 맴버로 둬서 고객의 이름을 저장했는데, 버전 2 Account 클래스에서는 이를 동적 할당 형태로 구현하자.
즉, Account 클래스는 맴버변수로 문자열 포인터를 지니고 있어야 한다.

또 한가지는 객체를 저장하는 배열에 관한 것이다.
객체 배열을 선언하지 말고, 객체 포인터 배열을 선언해서 객체를 저장하자.
1버전에서는 구조체배열을 선언했으니 이를 포인터 배열로 변경하자 !


구현

#include <iostream>
#include <cstring>

using namespace std;
const int NAME_LEN = 100;

void ShowMenu(void); // 메뉴 출력
void MakeAccount(void); // 계좌개설
void DepositMoney(void); // 입금
void WithdrawMoney(void); // 출금
void ShowAllAccInfo(void); // 잔액조회

enum {MAKE=1, DEPOSIT, WITHDRAW, INQUIRE, EXIT};

//typedef struct
//{
//    int accID; // 계좌번호
//    int balance; // 잔액
//    char cusName[NAME_LEN]; //고객 이름 -> 동적할당 형태로 변경
//}Account;
class Account
{
private:
    int accID;
    int balance;
    char * cusname;
public:
    Account(int accID,int balance,char * name):accID(accID),balance(balance)
    {
        cusname = new char[strlen(name)+1];
        strcpy(cusname, name);
    }
    int GetID() // 아이디 얻기
    {
        return accID;
    }
    void Deposit(int money) // 출 금
    {
        balance+=money;
    }
    int Withdraw(int money) // 인 출
    {
        if(balance<money)
            return 0;
        
        balance-=money;
        return money;
    }
    void ShowInfo() const // 정보
    {
        cout<<"계좌 ID"<<accID<<endl;
        cout<<"이 름"<<cusname<<endl;
        cout<<"잔 액"<<balance<<endl;
    }
    ~Account()
    {
        delete [] cusname;
            
    }
};

//Account accArr[100]; // Account 저장을 위한 배열 -> 객체 포인터 배열로 선언
Account * accArr[100];//Account 저장을 위한 포인터 배열
int accNum = 0; // 저장된 Account 수

int main(void)
{
    int choice;
    
    while(1)
    {
        ShowMenu();
        cout<<"선택 : ";
        cin>>choice;
        cout<<endl;
        
        switch (choice) {
            case MAKE: // 게좌계설
                MakeAccount();
                break;
            case DEPOSIT: // 입 금
                DepositMoney();
                break;
            case WITHDRAW: // 출금
                WithdrawMoney();
                break;
            case INQUIRE:
                ShowAllAccInfo();
                break;
            case EXIT:
                for(int i=0;i<accNum;i++)
                    delete accArr[i]; // 할당해제
                cout<<"계좌프로그램을 종료합니다."<<endl;
                return 0;
                break;
            default:
                cout<<"잘못된 숫자입니다 !! "<<endl;
        }
    }
}

//메뉴보여주기
void ShowMenu(void)
{
    cout<<"----MENU-----"<<endl;
    cout<<"1. 계좌개설"<<endl;
    cout<<"2. 입 금"<<endl;
    cout<<"3. 출 금"<<endl;
    cout<<"4. 계좌정보 전체 출력"<<endl;
    cout<<"5. 프로그램 종료"<<endl;
}

//계좌개설
void MakeAccount(void)
{
    int id; // id
    char name[NAME_LEN]; // name
    int balance; // 잔액
    
    cout<<"[계좌개설]"<<endl;
    cout<<"계좌 ID : "; cin>>id;
    cout<<"이  : "; cin>>name;
    cout<<"입금액 : "; cin>>balance;
    cout<<endl;

    accArr[accNum++] = new Account(id, balance, name); // 계좌 생성
//    accArr[accNum].accID=id;
//    accArr[accNum].balance=balance;
//    strcpy(accArr[accNum].cusName, name); //name정보를 배열에 저장
//    accNum++; // 사람 올려 ~
}

// 입금
void DepositMoney(void)
{
    int money;
    int id;
    cout<<"[입 금]"<<endl;
    cout<<"계좌 ID "; cin>>id;
    cout<<"입금액 : "; cin>>money;
    
    for(int i =0;i<accNum;i++)
    {
        if(accArr[i]->GetID() == id) // 빙빙빙 돌면서 accID를 찾는다
        {
            accArr[i]->Deposit(money);
            cout<<"입금완료 ! "<<endl<<endl;
            return; // 함수 탈출 !
        }else
            break;
    }
    cout<<"유효하지 않은 ID 입니다."<<endl<<endl; // accId 와 동일한 ID를 못찾으면 출력
}
// 출금
void WithdrawMoney(void)
{
    int money;
    int id;
    cout<<"[출 금]"<<endl;
    cout<<"계좌ID : "; cin>>id;
    cout<<"출금액 : "; cin>>money;
    
    for( int i=0;i<accNum;i++)
    {
        if(accArr[i]->GetID() == id) //아이디와 동일한 계좌 발견
        {
            if(accArr[i]->Withdraw(money)==0) // 액수 확인
            {
                cout<<"잔액부족..."<<endl<<endl;
                return;
            }
            cout<<"출금 완료"<<endl<<endl;
            return;
        }else
            break;
        
    }
    cout<<"유효하지 않은 ID 입니다."<<endl<<endl;
    
}

void ShowAllAccInfo(void)
{
    for(int i =0;i<accNum;i++)
    {
        accArr[i]->ShowInfo();
        cout<<endl;
    }
}

어떤가 !
생각보다 간단하지 않는가!
우선 구조체 Account를 없애고
클래스로 하여 객체를 생성해주는데 정보 은닉을 위해 accId 등등의 변수는 private로 하고 나머지 함수들은 퍼블릭에 둔다.

그리고 난 후 생성자를 통해서 cusname은 받는 길이만큼 동적할당 시켜준다.

그리고 나머지 함수들을 작성해서 각각의 기능들을 만들어준다.

그리하여 각 클래스 객체마다 저장하기위해 포인터 배열에 저장해두었다.

profile
Carnegie Mellon University Robotics Institute | Research Associate | Developing For Our Lives, 세상에 기여하는 삶을 살고자 개발하고 있습니다

0개의 댓글