[C++] 윤성우 열혈 - OOP 단계별 프로젝트 02단계 (class, 정보은닉, 캡슐화)

Kim Dongil·2022년 12월 7일
0

C++

목록 보기
6/23

버전 0.1 에서 만들었던 은행계좌 관리 프로그램을 버전 0.2 로 업그레이드 시켜보자.
구조체 Account 를 이번에 배운 클래스 Account 로 변경한다.

고민해봐야 할 두 가지

  • 어떻게 캡슐화를 시키고 정보를 은닉시켜야 하는지.

  • 생성자와 소멸자는 어떻게 정의해야 하는지.

두 가지 제약

  • 버전 0.1 은 char형 배열을 멤버로 둬서 고객의 이름을 저장했는데, 버전 0.2 는 동적 할당의 형태로 구현하자.
    (Account 클래스는 멤버변수로 문자열 포인터를 지니고 있어야 함)

  • 객체 포인터 배열을 선언해서 객체를 저장해보자.
    (버전 0.1 에서는 구조체 배열을 선언하였으니, 이를 포인터 배열로 변경해야 함)

#include <iostream>
#include <cstring>

using namespace std;
const int NAME_LEN = 20;

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

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

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

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

	int GetAccID() { return accID; }

	void Deposit(int money)
	{
		balance += money;
	}

	int Withdraw(int money)    // 출금액 반환, 부족 시 0
	{
		if (balance < money)
			return 0;

		balance -= money;
		return money;
	}

	void ShowAccInfo()
	{
		cout << "계좌ID: " << accID << endl;
		cout << "이  름: " << cusName << endl;
		cout << "잔  액: " << balance << endl;
	}

	~Account()
	{
		delete[]cusName;
	}
};

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:
			return 0;
		default:
			cout << "Illegal selection.." << endl;
		}
	}

	for (int i = 0; i < accNum; i++)
		delete accArr[i];
	return 0;
}

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;
	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 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]->GetAccID() == id)
		{
			accArr[i]->Deposit(money);
			cout << "입금완료" << endl << endl;
			return;
		}
	}
	cout << "유효하지 않은 ID 입니다." << endl << endl;
}

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]->GetAccID() == id)
		{
			if (accArr[i]->Withdraw(money) == 0)
			{
				cout << "잔액부족" << endl << endl;
				return;
			}

			cout << "출금완료" << endl << endl;
			return;
		}
	}
	cout << "유효하지 않은 ID 입니다." << endl << endl;
}

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

내가 겪은 시행착오

  1. private 하고있는 accID에 접근하려다가 오류 발생
    -> Account 클래스 내부에 GetAccId 함수를 만들고 GetAccId 함수를 통해서 accID 를 리턴값으로 받아내서 해결함. (136 줄)

  2. ~Account() 소멸자 생성해서 동적할당 했던 멤버변수 cusName 은 없앴지만 클래스 포인터배열 Account *accArr[100] 을 없애는 생각을 못했다. (95줄)

  3. if(accArr[i]->Withdraw(money) == 0) 에서 40줄 에서 return 0 을 반환 시켜두고 < 0 으로 써서 가지고 있는 돈 보다 더 많은 돈을 출금 시켰을때 정상적으로 출금이 됐다.
    따로 오류 코드가 안떠서 그냥 넘어갈 뻔했다. (158 줄)

  4. calss 내부 함수에 접근할때 관련 모든 코드를 . 으로 접근시켜서 오류가 대량 발생했다
    . 은 class 의 멤버를 직접 접근한다.
    ->은 포인터를 통해 멤버를 접근한다.
    Account * accArr[100]; Account 저장을 위한 포인터 배열을 만들었고 (59 줄)
    accArr[accNum++] = new Account(id, balance, name); 그 포인터 배열을 이용하여 new 연산자를 통해 동적할당을 했다 (123 줄)
    그러므로 . 으로 접근하는 방식이 아닌 -> 를 사용해야 한다.

C++ 과 C에서 화살표 함수 -> 와 .의 차이에 대해서 알아보겠습니다

0개의 댓글

관련 채용 정보