본문 바로가기
01.Bit 단기/C++

38_상속구조의 관점(계좌관리 실습)

by chojju 2018. 5. 3.
반응형

/*
상속 :
만약 하나의 부모에 다수의 자식이 있는 경우
1) 부모는 반드시 자식들의 공통 맴버변수,맴버함수
  를 갖는다.
2) 자식은 1) 자신만의 기능을 확장
             (맴버변수,맴버함수)추가
       2) 부모로부터 받은 기능을 개선/수정
       맴버함수의 오버라이딩

일반계좌 : 이름,잔액,계좌번호
           입금기능, 출금기능, 정보출력기능
기부계좌 : 이름,잔액,계좌번호,기부금합
           입금기능, 출금기능, 정보출력기능
     *1000*0.9 입금, 1000*0.1 기부
신용계좌 : 이름,잔액,계좌번호
           입금기능, 출금기능, 정보출력기능
     *1000*1.1 입금

부모 : 이름,잔액,계좌번호
       입금기능, 출금기능, 정보출력기능(이,잔,계)

자식1(일반계좌)

자식2(기부계좌) 기부금합
                정보출력기능 재정의
    입금기능 재정의

자식3(신용계좌)
                입금기능 재정의
*/


//Account.h

#pragma once
#include <iostream>
using namespace std;

class Account
{
private:
 string name;
 int balance;
 int id;
 static int s_id;

public:
 Account(string name, int balance = 0);
 ~Account();

public:
 string getName() const { return name; }
 int    getBalance() const { return balance; }
 int    getId() const { return id; }

public:
 virtual bool InputMoney(int money);
 bool OutputMoney(int money);
 virtual void Print() const;
};


//BitArrayList.h

#pragma once
/*
int arr[10] : 정수 10개 저장
int *arr    : 정수 N개 저장
arr = (int*)malloc(sizeof(int)*N);

int *arr[10]: 정수 주소 10개 저장
int * *arr   : 정수 주소 N개 저장
arr = (int**)malloc(sizeof(int*)*N);
*/

class BitArrayList
{
 void* * arr;  //저장소
 int   max; //저장 최대값
 int   size; //저장개수 및 저장할위치

public:
 BitArrayList(int max = 10);
 ~BitArrayList();

public:
 int getMax() { return max; }
 int getSize() { return size; }
 void* getData(int idx) { return arr[idx]; }

public:
 bool pushBack(void *value);
 bool Erase(int idx);
private:
 bool isOverflow();
};


 

#pragma once
#include "Account.h"

class ContriAccount : public Account
{
private:
 int contribution;

public:
 ContriAccount(string name, int balance = 0);
 ~ContriAccount();

public:
 int getContribution() const { return contribution; }

public:
 bool InputMoney(int money);
 void Print() const;
};

 


 

#pragma once
#include "BitArrayList.h"

class Control
{
 BitArrayList *alist;
public:
 Control();
 ~Control();

public:
 void Insert();
 void SelectAll();
 void Select();
 void Update_Input();
 void Update_Output();
 void Delete();
 void SelectType();
 void Update_IO();

};


//FaithAccount.h

#pragma once

#include "Account.h"

class FaithAccount : public Account
{
public:
 FaithAccount(string name, int balance = 0);
 ~FaithAccount();

public:
 bool InputMoney(int money);
};


//Account.cpp

#include "Account.h"

int Account::s_id = 1000;

Account::Account(string name, int balance /*= 0*/)
 : name(name), balance(balance)
{
 id = s_id;

 s_id = s_id + 10;
}


Account::~Account()
{
}

bool Account::InputMoney(int money)
{
 if (money <= 0)  return false;

 balance += money;
 return true;
}

bool Account::OutputMoney(int money)
{
 if (money <= 0)   return false;
 if (money > balance) return false;

 balance -= money;
 return true;
}

void Account::Print() const
{
 printf("[계좌번호]%-7d[이름]%-10s[잔액]%-10d",
  id, name.c_str(), balance);
}


//BitArrayList.cpp

#include <iostream>
using namespace std;
#include "BitArrayList.h"

BitArrayList::BitArrayList(int max /*=10*/)
{
 size = 0;
 //this : 자신의 개체 주소를 갖는 변수
 this->max = max;

 // arr = (int**)malloc(sizeof(int*)*max);
 arr = new void*[max];
}


BitArrayList::~BitArrayList()
{
 // free(arr);
 delete[] arr;
}

bool BitArrayList::pushBack(void *value)
{
 if (isOverflow() == true)
  return false;

 arr[size] = value;
 size++;
 return true;
}

bool BitArrayList::isOverflow()
{
 if (max <= size) return true;
 else    return false;
}

bool BitArrayList::Erase(int idx)
{
 if (idx >= 0 && idx < size)
 {
  delete arr[idx]; //<= 동적메모리삭제

  for (int i = idx; i < size - 1; i++)
  {
   arr[i] = arr[i + 1];
  }
  size--;
  return true;
 }
 else
  return false;
}


//ContriAccount.cpp

#include "ContriAccount.h"


ContriAccount::ContriAccount(string name, int balance /*= 0*/)
 :Account(name, balance)
{
 contribution = 0;
}


ContriAccount::~ContriAccount()
{
}
//1000*0.9 입금, 1000*0.1 기부
bool ContriAccount::InputMoney(int money)
{
 if (money < 0)  return false;

 contribution += (int)(money*0.1);
 return Account::InputMoney((int)(money*0.9));
}

void ContriAccount::Print() const
{
 Account::Print();
 printf("[기부금]%-10d", contribution);
}


//Control.cpp

#include <iostream>
using namespace std;

#include "Control.h"
#include "BitArrayList.h"
#include "Account.h"
#include "FaithAccount.h"
#include "ContriAccount.h"

Control::Control()
{
 int num;
 cout << "최대 저장개수 : ";
 cin >> num;
 alist = new BitArrayList(num);
}

Control::~Control()
{
 delete alist;
}


void Control::Insert()
{
 //1. 저장할 정보 생성
 char name[20];
 int  balance;
 int  type;
 getchar();
 cout << "이름 입력 : ";
 cin.getline(name, sizeof(name));
 cout << "입금액 입력 : ";
 cin >> balance;
 cout << "계좌 종류([1]일반[2]기부[3]신용) 입력 : ";
 cin >> type;


 //2. 저장할 객체 생성
 Account *pacc;
 switch (type)
 {
 case 1: pacc = new Account(name, balance);   break;
 case 2: pacc = new ContriAccount(name, balance); break;
 case 3: pacc = new FaithAccount(name, balance); break;
 }

 //3. 저장 요청
 if (alist->pushBack(pacc) == true)
  cout << "저장되었습니다." << endl;
 else
  cout << "저장공간이 없습니다." << endl;
}

void Control::SelectAll()
{
 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *p = (Account*)alist->getData(i);
  p->Print();
  cout << endl;
 }
 cout << endl;
}

void Control::Select()
{
 char key[20];
 cout << "검색할 이름 입력 : ";
 getchar();
 cin.getline(key, sizeof(key));

 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *p = (Account*)alist->getData(i);
  if (strcmp(key, p->getName().c_str()) == 0)
  {
   cout << "[인덱스] " << i << endl;
   p->Print();
   cout << endl;
   return;
  }
 }
 cout << "데이터가 존재하지 않습니다." << endl;
}

void Control::Update_Input()
{
 char key[20];
 cout << "입금할 이름 검색 : ";
 getchar();
 cin.getline(key, sizeof(key));

 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *p = (Account*)alist->getData(i);
  if (strcmp(key, p->getName().c_str()) == 0)
  {
   int  money;
   cout << "입금액  : ";
   cin >> money;
   if (p->InputMoney(money))
    cout << "입금 되었습니다." << endl;
   else
    cout << "입금 오류입니다." << endl;
   return;
  }
 }
 cout << "데이터가 존재하지 않습니다." << endl;
}

void Control::Update_Output()
{
 char key[20];
 cout << "출금할 이름 검색 : ";
 getchar();
 cin.getline(key, sizeof(key));

 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *p = (Account*)alist->getData(i);
  if (strcmp(key, p->getName().c_str()) == 0)
  {
   int  money;
   cout << "출금액  : ";
   cin >> money;
   if (p->OutputMoney(money))
    cout << "출금 되었습니다." << endl;
   else
    cout << "출금 오류입니다." << endl;
   return;
  }
 }
 cout << "데이터가 존재하지 않습니다." << endl;
}

void Control::Delete()
{
 char key[20];
 cout << "삭제할 이름 입력 : ";
 getchar();
 cin.getline(key, sizeof(key));

 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *p = (Account*)alist->getData(i);
  if (strcmp(key, p->getName().c_str()) == 0)
  {
   alist->Erase(i);
   cout << "삭제되었습니다." << endl;
   return;
  }
 }
 cout << "데이터가 존재하지 않습니다." << endl;
}

void Control::SelectType()
{
 int type;
 cout << "검색할 계좌 종류([1]일반계좌 [2]기부계좌 [3]신용계좌) : ";
 cin >> type;

 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *pacc = (Account *)alist->getData(i);
  Account *pc = NULL;
  if (type == 2)
   pc = dynamic_cast<ContriAccount*>(pacc);
  else if (type == 3)
   pc = dynamic_cast<FaithAccount*>(pacc);
  else if (type == 1)
  {
   if (!dynamic_cast<ContriAccount*>(pacc) &&
    !dynamic_cast<FaithAccount*>(pacc))
    pc = dynamic_cast<Account*>(pacc);
  }

  if (pc != NULL)
  {
   pacc->Print();
   cout << endl;
  }
 }
}


void Control::Update_IO()
{
 char input[20], output[20];
 int  money;
 getchar();
 cout << "출금계좌 : ";
 cin.getline(output, sizeof(output));
 cout << "입금계좌 : ";
 cin.getline(input, sizeof(input));
 cout << "이체금액 : ";
 cin >> money;
 //============================================
 //출금계좌 검색
 Account *accoutput = NULL;
 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *p = (Account*)alist->getData(i);
  if (strcmp(output, p->getName().c_str()) == 0)
  {
   accoutput = p;
  }
 }
 //입금계좌 검색
 Account *accinput = NULL;
 for (int i = 0; i < alist->getSize(); i++)
 {
  Account *p = (Account*)alist->getData(i);
  if (strcmp(input, p->getName().c_str()) == 0)
  {
   accinput = p;
  }
 }
 //==========================================
 if (accinput != NULL && accoutput != NULL)
 {
  if (accoutput->OutputMoney(money) == false)
   cout << "출금계좌 잔액 부족" << endl;
  else {
   accinput->InputMoney(money);
   cout << "정상적으로 이체되었습니다." << endl;
  }
 }
 else
  cout << "계좌를 찾을 수 없습니다." << endl;
}


//FaithAccount.cpp

#include "FaithAccount.h"

 

FaithAccount::FaithAccount(string name, int balance /*= 0*/)
 :Account(name, balance)
{
}


FaithAccount::~FaithAccount()
{
}

//1000*1.1 입금
bool FaithAccount::InputMoney(int money)
{
 return Account::InputMoney((int)(money*1.1));
}


//소스.cpp

#include <iostream>
using namespace std;
#include "Control.h"

int main()
{
 Control *con = new Control;
 int idx;
 while (true)
 {
  system("cls");
  con->SelectAll();
  cout << "====================================================" << endl;
  cout << "[1]입력 [2]검색 [3]수정(입금) [4]수정(출금)  [5]삭제 " << endl;
  cout << "[6]특정계좌검색 [7]계좌이체   [8]종료" << endl;
  cout << "====================================================" << endl;
  cin >> idx;
  switch (idx)
  {
  case 1: con->Insert();    break;
  case 2: con->Select();    break;
  case 3: con->Update_Input();  break;
  case 4: con->Update_Output();  break;
  case 5: con->Delete();    break;
  case 6: con->SelectType();   break;
  case 7: con->Update_IO();   break;
   //  case 5: con->LogPrint(); break;
  case 8: return 0;
  }
  system("pause");
 }
 delete con;
 return 0;
}

 

반응형

'01.Bit 단기 > C++' 카테고리의 다른 글

40_암시적명시적 사용  (0) 2018.05.08
39_함수템플릿  (0) 2018.05.08
37_다중상속및 모호성2(virtual)  (0) 2018.05.03
36_다중상속및 모호성1  (0) 2018.05.03
35_다중상속  (0) 2018.05.03

댓글