[C++] 윤성우 열혈 - OOP 단계별 프로젝트 05단계 (상속의 이해)

Kim Dongil·2022년 12월 10일
0

C++

목록 보기
9/23

버전 0.4 에서 만들었던 은행계좌 관리 프로그램을 버전 0.5 로 업그레이드 시켜보자.

컨트롤 클래스의 특징

  • 프로그램 전체의 기능을 담당한다. 따라서 기능적 성격이 강한 클래스이다.

  • 컨트롤 클래스만 봐도 프로그램의 전체 기능과 흐름을 파악할 수 있다.

반면, 컨트롤 클래스가 아닌 대부분의 클래스를 가리켜 'Entity 클래스' 라 한다.

Entity 클래스의 특징

  • 데이터적 성격이 강하다. 따라서 파일 및 데이터 베이스에 저장되는 데이터를 소유하고 있다.

  • 프로그램의 기능을 파악하는데 도움을 주지는 못한다.

  • 그러나 프로그램상에서 관리되는 데이터의 종류를 파악하는 데는 도움이 된다.

우리가 구현하고 있는 Bangking System 의 주요기능은 다음과 같다. (버전 0.4)

  • 계좌개설
  • 입 금
  • 출 금
  • 계좌정보 전체 출력

이러한 기능은 전역함수를 통해서 구현되어 있다. 그러나 객체지향에서는 '전역' 이라는 개념이 존재하지 않는다.
비록 C++ 에서는 전역함수와 전역변수의 선언을 허용하고 있지만, 이는 객체지향 프로그래밍을 위한것은 아니니 가급적 사용하지 않는 것이 좋다.
기능적 성격이 강한 컨트롤 클래스를 등장시키면, 우리가 구현하고 있는 단계별 프로젝트에서 전역함수들을 없앨 수 있다.

버전 0.5 에서 구현해야 할 컨트롤 클래스의 구현방법

  • AccountHandler 라는 이름의 컨트롤 클래스를 정의하고, 앞서 정의한 전역함수들을 이 클래스의 멤버함수에 포함시킨다.

  • Account 객체의 저장을 위해 선언한 배열과 변수도 이 클래스의 멤버에 포함시킨다.

#include <iostream>
#include <cstring>

using namespace std;
const int NAME_LEN = 20;

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

class Account {
	int accID;      // 계좌번호
	int balance;    // 잔    액
	char* cusName;   // 고객이름

public:
	Account(int ID, int money, char* name);
	Account(const Account& copy);
	int GetAccID() const;
	void Deposit(const int money);
	int Withdraw(const int money); // 출금액 반환, 부족 시 0
	void ShowAccInfo() const;
	~Account();
};

Account::Account(int ID, int money, char* name)
	: accID(ID), balance(money) {
	cusName = new char[strlen(name) + 1];
	strcpy(cusName, name);
}
Account::Account(const Account& copy) : accID(copy.accID), balance(copy.balance) {
	cusName = new char[strlen(copy.cusName) + 1];
	strcpy(cusName, copy.cusName);
}

int Account::GetAccID() const { return accID; }

void Account::Deposit(const int money) {
	balance += money;
}
int Account::Withdraw(const int money) {
	if (balance < money)
		return 0;

	balance -= money;
	return money;
}
void Account::ShowAccInfo() const {
	cout << "계좌ID: " << accID << endl;
	cout << "이  름: " << cusName << endl;
	cout << "잔  액: " << balance << endl;
}
Account::~Account() {
	delete[]cusName;
}

class AccountHandler {
	Account* accArr[100]; // Account 저장을 위한 배열
	int accNum; // 저장된 Account 수
public:
	AccountHandler();
	void ShowMenu() const;       // 메뉴출력
	void MakeAccount();    // 계좌개설을 위한 함수
	void DepositMoney();       // 입    금
	void WithdrawMoney();      // 출    금
	void ShowAllAccInfo() const;     // 잔액조회
	~AccountHandler();
};

AccountHandler::AccountHandler() : accNum(0) {}

void AccountHandler::ShowMenu() const {
	cout << "-----Menu------" << endl;
	cout << "1. 계좌개설" << endl;
	cout << "2. 입    금" << endl;
	cout << "3. 출    금" << endl;
	cout << "4. 계좌정보 전체 출력" << endl;
	cout << "5. 프로그램 종료" << endl;
}
void AccountHandler::MakeAccount() {
	int id;
	char name[NAME_LEN];
	int balance;

	cout << "[계좌개설]" << endl;
	cout << "계좌ID: ";	cin >> id;
	cout << "이  름: ";	cin >> name;
	cout << "입금액: ";	cin >> balance;
	cout << endl;

	accArr[accNum++] = new Account(id, balance, name);
}
void AccountHandler::DepositMoney() {
	int money;
	int id;
	cout << "[입    금]" << endl;
	cout << "계좌ID: ";	cin >> id;
	cout << "입금액: ";	cin >> money;

	for (int i = 0; i < accNum; i++)
	{
		if (accArr[i]->GetAccID() == id)
		{
			accArr[i]->Deposit(money);
			cout << "입금완료" << endl << endl;
			return;
		}
	}
	cout << "유효하지 않은 ID 입니다." << endl << endl;
}
void AccountHandler::WithdrawMoney() {
	int money;
	int id;
	cout << "[출    금]" << endl;
	cout << "계좌ID: ";	cin >> id;
	cout << "출금액: ";	cin >> money;

	for (int i = 0; i < accNum; i++)
	{
		if (accArr[i]->GetAccID() == id)
		{
			if (accArr[i]->Withdraw(money) == 0)
			{
				cout << "잔액부족" << endl << endl;
				return;
			}

			cout << "출금완료" << endl << endl;
			return;
		}
	}
	cout << "유효하지 않은 ID 입니다." << endl << endl;
}
void AccountHandler::ShowAllAccInfo() const {
	for (int i = 0; i < accNum; i++)
	{
		accArr[i]->ShowAccInfo();
		cout << endl;
	}
}
AccountHandler::~AccountHandler() {
	for (int i = 0; i < accNum; i++)
		delete accArr[i];
}

int main(void) {
	AccountHandler  handler;
	int choice;

	while (1) {
		handler.ShowMenu();
		cout << "선택: ";
		cin >> choice;
		cout << endl;

		switch (choice) {
		case MAKE:
			handler.MakeAccount();
			break;
		case DEPOSIT:
			handler.DepositMoney();
			break;
		case WITHDRAW:
			handler.WithdrawMoney();
			break;
		case INQUIRE:
			handler.ShowAllAccInfo();
			break;
		case EXIT:
			cout << "프로그램을 종료합니다." << endl;
			return 0;
		default:
			cout << "잘못된 입력입니다. 다시 입력해 주세요" << endl;
		}
	}

	return 0;
}

0.4 버전과 다른점
-> 전역함수로 만들어놨던 기능들을 AccountHandler 라는 class 를 새로 만들어서 집어넣었고,
Account 객체의 저장을 위해 선언한 배열과 변수도 이 클래스의 멤버에 넣었다.
또한 그에 맞춰서 main 함수를 변경했다.

0개의 댓글

관련 채용 정보