Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

Dev fox

열혈 C++ 프로그래밍 OOP 프로젝트 06 본문

C++

열혈 C++ 프로그래밍 OOP 프로젝트 06

나른한여우 2024. 3. 22. 18:54

06. 클래스의 상속 추가와 virtual 가상함수를 선언해 같은 이름으로 오버라이딩된 함수를 사용함

userList의 포인터형은 Account로 선언했지만 nomalAccount와 creditAccount의 주소값을 받을수있는

이유는 IS-A형으로 Account, NomalAccount, HighCreditAccount클래스가 상속받고 있기때문이다.

 

가상함수로 선언한 Deposit을 상황에 맞게 불러올수 있는 이유도 userList가 Account 포인터형이지만

이 포인터가 가리키는 객체가 생성되는 과정에서 NomalAccount와 HighCreditAccount로 나뉘기때문

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

// 02 class추가, 객체 포인터 배열 추가
// 03 복사 생성자 추가, 소멸자 추가
// 04 Account 클래스내의 const선언이 가능한 멤버함수에 const선언
// 05 전반적인 기능을 담당하는 Handler 컨트롤 클래스 추가
// 06 클래스 상속 추가

enum { MAKE = 1, DEPOSIT, WITHDRAW, INQUIRE, EXIT };
enum { LEVEL_A = 1, LEVEL_B, LEVEL_C};
enum { NORMAL = 1, CREDIT };

class Account
{
private:
	int accId;
	int balance;
	char* cusName;
public:
	Account(const int id, int money,const char* name)
		:accId(id), balance(money)
	{
		cusName = new char[strlen(name) + 1];
		strcpy_s(cusName, strlen(name) + 1, name);
	}

	Account(const Account& ac)
		:accId(ac.accId), balance(ac.balance)
	{
		cusName = new char[strlen(ac.cusName) + 1];
		strcpy_s(cusName, strlen(ac.cusName) + 1, ac.cusName);
	}
	int GetAccId() const
	{
		return accId;
	}
	virtual void Deposit(int money)
	{
		balance += money;
	}
	int WithDraw(int money)
	{
		if (balance < money)
		{
			return 0;
		}
		balance -= money;
		return money;
	}
	void ShowAccount() const
	{
		cout << "계좌번호: " << accId << endl;
		cout << "고객이름: " << cusName << endl;
		cout << "잔 액: " << balance << endl<<endl;
	}
	~Account()
	{
		delete[]cusName;
	}
};

class NomalAccount : public Account
{
private:
	int interestInfo;
public:
	NomalAccount(const int id, int money, const char* name, int interInfo)
		:Account(id, money, name), interestInfo(interInfo)
	{}
	virtual void Deposit(int money)
	{
		Account::Deposit(money);
		Account::Deposit(money * (interestInfo*0.01));
	}
};

class HighCreditAccount : public NomalAccount
{
private:
	int rating;
public:
	HighCreditAccount(const int id, int money, const char* name, int interInfo, int rate)
		:NomalAccount(id, money, name, interInfo), rating(rate)
	{}
	virtual void Deposit(int money)
	{
		NomalAccount::Deposit(money);
		switch (rating)
		{
			case LEVEL_A:
				Account::Deposit((int)money * 0.07);
				break;
			case LEVEL_B:
				Account::Deposit((int)money * 0.04);
				break;
			case LEVEL_C:
				Account::Deposit((int)money * 0.02);
				break;
		}
	}
};

//handler 클래스 추가
class AccountHandler
{
private:
	Account* userList[100];
	int userIndex;
public:
	AccountHandler()
		:userIndex(0)
	{ }

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

	void MakeAccount() {
		int interInfo;
		cout << "[계좌종류선택]" << endl;
		cout << "1.보통예급계좌 2.신용신뢰계좌" << endl;
		cout << "선택: ";
		cin >> interInfo;
		if(interInfo == NORMAL)
			MakeNomalAccount();
		else 
			MakeCreditAccount();
	}

	void MakeNomalAccount()
	{
		int id;
		int money = 0;
		int interInfo;
		char userName[30];

		cout << "[보통예금계좌 개설]" << endl;
		cout << "계좌ID: ";
		cin >> id;
		cout << "고객이름: ";
		cin >> userName;
		cout << "이자율: ";
		cin >> interInfo;
		userList[userIndex++] = new NomalAccount(id, money, userName, interInfo);
		cout << endl;
	}

	void MakeCreditAccount()
	{
		int id;
		int money = 0;
		int interInfo;
		int rate;
		char userName[30];

		cout << "[신용신뢰계좌 개설]" << endl;
		cout << "계좌ID: ";
		cin >> id;
		cout << "고객이름: ";
		cin >> userName;
		cout << "이자율: ";
		cin >> interInfo;
		cout << "신용등급(1toA, 2toB, 3toC): ";
		cin >> rate;
		userList[userIndex++] = new HighCreditAccount(id, money, userName, interInfo, rate);
		cout << endl;
	}

	void DepositMoney() {
		int tempId;
		int tempBalance;

		cout << "[입 금]" << endl;
		cout << "입금할 계좌번호: ";
		cin >> tempId;
		for (int i = 0; i < userIndex; i++)
		{
			if (tempId == userList[i]->GetAccId())
			{
				cout << "입금할 금액: ";
				cin >> tempBalance;
				userList[i]->Deposit(tempBalance);
				cout << endl;
				return;
			}
		}
		cout << "유효하지 않은 ID 입니다." << endl << endl;
	}

	void WithdrawMoney() {
		int tempId;
		int tempBalance;

		cout << "[출 금]" << endl;
		cout << "출금할 계좌번호: ";
		cin >> tempId;
		for (int i = 0; i < userIndex; i++)
		{
			if (tempId == userList[i]->GetAccId())
			{
				cout << "출금할 금액: ";
				cin >> tempBalance;
				if (userList[i]->WithDraw(tempBalance) == 0)
				{
					cout << "잔액 부족" << endl << endl;
					return;
				}
				cout << "출금완료" << endl;
				cout << endl;
				return;
			}
		}
		cout << "유효하지 않은 ID 입니다." << endl << endl;
	}

	void ShowAllAccount() {
		for (int i = 0; i < userIndex; i++)
		{
			userList[i]->ShowAccount();
		}
	}

	~AccountHandler()
	{
		for (int i = 0; i < userIndex; i++)
			delete userList[i];
	}
};

int main(void) 
{
	AccountHandler controller;

	int choice;

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

		switch(choice)
		{
			case MAKE:
				controller.MakeAccount();
				break;
			case DEPOSIT:
				controller.DepositMoney();
				break;
			case WITHDRAW:
				controller.WithdrawMoney();
				break;
			case INQUIRE:
				controller.ShowAllAccount();
				break;
			case EXIT:
				return 0;
		}
	}

	return 0;
}