본문 바로가기
C++

OOP (Object-Oriented-Project)

by KWONE 2024. 8. 7.

OOP 단계별 프로젝트 01단계

 

#include <iostream>
#include "banking.h"

using namespace std;
typedef struct information {
	int ID;
	char name[100];
	int money;
}psinfo;

psinfo customers[1000];

void printmenu()
{
	cout << "-----Menu-----" << endl;
	cout << "1. 계좌 개설" << endl;
	cout << "2. 입금" << endl;
	cout << "3. 출금" << endl;
	cout << "4. 계좌정보 전체 출력" << endl;
	cout << "5. 프로그램 종료" << endl;
	cout << endl;
	cout << endl;
}

int select_menu()
{
	int choice;
	cout << "선택 : ";
	cin >> choice;
	if (choice == 1) {
		open_account();
	}
	if (choice == 2) {
		deposit();
	}
	if (choice == 3) {
		withdraw();
	}
	if (choice == 4) {
		printinfo();
	}
	if (choice == 5) {
		return 0;
	}
	else {
		cout << "잘못된 접근!" << endl;
		return 0;
	}
}

void open_account()
{
	int dpmoney;
	int ID;
	cout << "계좌 ID : ";
	cin >> ID;
	customers[ID].ID = ID;
	cout << "이름 : ";
	cin >> customers[ID].name;
	cout << "입금액 : ";
	cin >> dpmoney;
	customers[ID].money += dpmoney;
	cout << endl;
}

void deposit()
{
	int dpmoney = 0;
	int ID;
	cout << "[입	금]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "입금액 : ";
	cin >> dpmoney;
	customers[ID].money += dpmoney;
	cout << endl;
}

void withdraw()
{
	int wdmoney = 0;
	int ID;
	cout << "[출	금]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "입금액 : ";
	cin >> wdmoney;
	customers[ID].money -= wdmoney;
	cout << endl;
}

void printinfo()
{
	int ID;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "이름 : " << customers[ID].name;
	cout << "잔액 : " << customers[ID].money;
	cout << endl;
}

int main()
{
	while (1) {
		printmenu();
		select_menu();
	}
	
	return 0;
}

 

OOP 단계별 프로젝트 02 단계

Ver2로 업그레이드 하기위해 수정해야할 것들

  1. 열거형 사용해서 select_menu() 함수 수정하기
  2. 객체 포인터 배열로 계좌 정보 받기
  3. 멤버변수 이름을 동적할당하여 이름 크기만큼만 메모리 할당 받기
  4. struct 대신 class를 사용하면서 좋은 캡슐화와 정보은닉 생각 하기

아래는 수정된 BankingSystemVer2.cpp 이다. 편의상 헤더파일(Banking.h) 은 따로 정의하였다.

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;

void print_menu();
int select_menu();
void open_account();
void deposit();
void withdraw();
void print_info();

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

typedef struct  {
	int accID;
	char *cusName;
	int balance;
}Account;

Account* accArr[1000];

void print_menu()
{
	cout << "-----Menu-----" << endl;
	cout << "1. 계좌 개설" << endl;
	cout << "2. 입금" << endl;
	cout << "3. 출금" << endl;
	cout << "4. 계좌정보 전체 출력" << endl;
	cout << "5. 프로그램 종료" << endl;
	cout << endl;
	cout << endl;
}

int select_menu()
{
	int choice;
	cout << "선택 : ";
	cin >> choice;
	switch (choice)
	{
	case MAKE:
		open_account();
		break;
	case DEPOSIT:
		deposit();
		break;
	case WITHDRAW:
		withdraw();
		break;
	case INQUIRE:
		print_info();
		break;
	case EXIT:
		return 0;
	default:
		cout << "Illegal selection.." <<endl;
	}
	
}

void open_account()
{
	int dpmoney;
	int ID;
	char name[100];
	cout << "[계좌개설]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	accArr[ID] = new Account();
	accArr[ID]->accID = ID;
	cout << "이름 : ";
	cin >> name;
	cout << "입금액 : ";
	cin >> dpmoney;

	accArr[ID]->cusName = new  char[strlen(name)+1];
	accArr[ID]->balance += dpmoney;
	strcpy(accArr[ID]->cusName, name);
	cout << endl;
}

void deposit()
{
	int dpmoney = 0;
	int ID;
	cout << "[입	금]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "입금액 : ";
	cin >> dpmoney;
	accArr[ID]->balance += dpmoney;
	cout << endl;
}

void withdraw()
{
	int wdmoney = 0;
	int ID;
	cout << "[출	금]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "출금액 : ";
	cin >> wdmoney;
	accArr[ID]->balance -= wdmoney;
	cout << endl;
}

void print_info()
{
	int ID;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "이름 : " << accArr[ID]->cusName<<endl;
	cout << "잔액 : " << accArr[ID]->balance << endl;
	cout << endl;
}

int main()
{

	while (1) {
		print_menu();
		select_menu();
	}

	return 0;
}

우선 Account의 멤버변수 중 이름을 저장하는 cusName을 문자열의 크기에 맞게 동적할당하여 초기화 하도록 하였고,

구조체 포인터 배열을 사용하여 나타내었다. 이제는 구조체를 class로 전부 바꿔서 넣어보겠다. 

그 이후 정보은닉과 캡슐화를 신경써서 한번더 검토해 보자.

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
enum {MAKE=1,DEPOSIT,WITHDRAW,INQUIRE,EXIT};

class Account {
	int accID;
	char* cusName;
	int balance;

public:
	void print_menu() const;
	int select_menu();
	void open_account();
	void deposit();
	void withdraw();
	void print_info() const;
};

Account* accArr[1000];

void Account::print_menu() const
{
	cout << "-----Menu-----" << endl;
	cout << "1. 계좌 개설" << endl;
	cout << "2. 입금" << endl;
	cout << "3. 출금" << endl;
	cout << "4. 계좌정보 전체 출력" << endl;
	cout << "5. 프로그램 종료" << endl;
	cout << endl;
	cout << endl;
}

int Account::select_menu()
{
	int choice;
	cout << "선택 : ";
	cin >> choice;
	switch (choice)
	{
	case MAKE:
		open_account();
		break;
	case DEPOSIT:
		deposit();
		break;
	case WITHDRAW:
		withdraw();
		break;
	case INQUIRE:
		print_info();
		break;
	case EXIT:
		return 0;
	default:
		cout << "Illegal selection.." << endl;
	}
}

void Account::open_account()
{
	int dpmoney;
	int ID;
	char name[100];
	cout << "[계좌개설]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	accArr[ID] = new Account();
	accArr[ID]->accID = ID;
	cout << "이름 : ";
	cin >> name;
	cout << "입금액 : ";
	cin >> dpmoney;

	accArr[ID]->cusName = new  char[strlen(name) + 1];
	accArr[ID]->balance += dpmoney;
	strcpy(accArr[ID]->cusName, name);
	cout << endl;
}

void Account::deposit()
{
	int dpmoney = 0;
	int ID;
	cout << "[입	금]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "입금액 : ";
	cin >> dpmoney;
	accArr[ID]->balance += dpmoney;
	cout << endl;
}

void Account::withdraw()
{
	int wdmoney = 0;
	int ID;
	cout << "[출	금]" << endl;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "출금액 : ";
	cin >> wdmoney;
	accArr[ID]->balance -= wdmoney;
	cout << endl;
}

void Account::print_info() const
{
	int ID;
	cout << "계좌 ID : ";
	cin >> ID;
	cout << "이름 : " << accArr[ID]->cusName << endl;
	cout << "잔액 : " << accArr[ID]->balance << endl;
	cout << endl;
}

int main()
{
	Account person;
	while (1) {
		person.print_menu();
		if (person.select_menu() == 0) {
			break; 
		}
	}
	return 0;
}

위 코드는 구조체를 class Account 로 바꾸고 멤버변수를 모두 private 선언한뒤에 초기화하는 함수를 public으로 따로 정의하였다. 사용자로 부터 값을 입력받아 초기화하므로 생성자나 이니셜라이저 사용이 어울리는지는 아직 잘 모르겠다.

코드를 만들며 아쉬운점은 우선적으로 캡슐화가 안되어있는것 같고, 파일의 입출력스트림이 일회성이므로 프로그램 실행후 정보가 저장되지않는다는 점이다. 이는 파일의 입출력 시스템 함수들로 해결할 수 있을것 같아 보인다.

또한 객체 포인터 배열 사용에 익숙하지 않아, 포인터 생성후 초기화를 어떻게 해야하는지 아직 의문이 남는다. 다음 단계를 진행하면서 차차 생각해보아야 겠음.

OOP 단계별 프로젝트 03 단계

 

WIP

 

'C++' 카테고리의 다른 글

문제 04-3 [C++ 기반의 데이터 입출력]  (0) 2024.08.06
문제 04-2 [다양한 클래스의 정의]  (0) 2024.08.05
문제 04-1 [정보은닉과 const]  (0) 2024.08.05
Class 활용 예제  (0) 2024.08.05
문제 03-2 [클래스의 정의]  (0) 2024.08.02