25.08.04 학습개발일지 / C++ Study6(2)

2025. 8. 4. 22:59·LMS 7/개발일지

과제3.

p.376

챕터 목표: *멤버함수가 실제로 어디에 존재하는지를 설명

> 멤버함수는 메모리 중 별도의 공간에 존재하고, 해당 클래스를 참조하는 객체가 이 함수를 공유하는 형태임


p.377~382

가상함수의 동작 원리를

1) 메모리 관점에서

2) 객체 사이즈와

3) 가상함수 테이블과

4) 런타임용어를 사용해 설명할 것

#include <iostream>
using namespace std;

class A {
    int x;
};

class B {
    int x;
    void func() {}
};

int main() {
    cout << "sizeof(A): " << sizeof(A) << endl;
    cout << "sizeof(B): " << sizeof(B) << endl;
}

#include <iostream>
using namespace std;

class A {
    int x;
};

class B {
    int x;
    virtual void func() {}
};

int main() {
    cout << "sizeof(A): " << sizeof(A) << endl;
    cout << "sizeof(B): " << sizeof(B) << endl;
}

> 가상함수는 컴파일시 메모리 중 별도의 공간에 가상함수 테이블을 생성하여, 실제 객체 생성과 상관없이 메모리 공간에 할당된다. 하지만 이 경우 생성된 객체 내부에는 가상함수 테이블에 대한 포인터가 자동으로 포함되기 때문에 객체 사이즈에 영향을 준다. 가상함수 테이블 포인터는 64비트 체제에서 8byte의 크기를 가지고 있음.


p.390

프로젝트 07단계

 

<Account.h>

//Account.h
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__

class Account
{
private:
	int accID; 
	int balance;    
	char * cusName; 
public:
	Account(int ID, int money, char * name);
	Account(const Account & ref);

	int GetAccID() const;
	virtual void Deposit(int money);
	int Withdraw(int money) ;
	void ShowAccInfo() const ;
	~Account();
};
#endif

 

<Account.cpp>

// Account.cpp
#include "BankingCommonDecl.h"
#include "Account.h"

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 & ref)
	: accID(ref.accID), balance(ref.balance)
{
	cusName=new char[strlen(ref.cusName)+1];
	strcpy(cusName, ref.cusName);
}

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

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

int Account::Withdraw(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;
}

> Account와 이를 상속받은 클래스들은 사전에 선언되어 있는 데이터들을 관리하기 위한 데이터 클래스이다.

> Account(기초 클래스)에 대한 선언(.h)과 정의(.cpp)에 대한 파일임

> Deposit 멤버함수는 실제 객체를 생성할 때 유도 클래스를 기준으로 함수를 호출하기 위해 가상함수(virtual)가 사용됨

 

<NormalAccount.h>

// NormalAccount.h
#ifndef __NORMAL_ACCOUNT_H__
#define __NORMAL_ACCOUNT_H__

#include "Account.h"

class NormalAccount : public Account
{
private:
	int interRate;   // 이자율 %단위
public:
	NormalAccount(int ID, int money, char * name, int rate)
		: Account(ID, money, name), interRate(rate)
	{  }
	virtual void Deposit(int money)
	{
		Account::Deposit(money);        // 원금추가
		Account::Deposit(money*(interRate/100.0));   // 이자추가
	}
};
#endif

> Account 클래스의 상속을 받은 NormalAccount 클래스임

> 기초 클래스의 virtual 선언으로 유도 클래스의 virtual 선언은 필요하지 않지만 가독성을 위해서는 붙여주는 것을 권장하고 있음

 

<HighCreditAccount.h>

// HighCreditAccount.h
#ifndef __HIGHCREDIT_ACCOUNT_H__
#define __HIGHCREDIT_ACCOUNT_H__

#include "NormalAccount.h"

class HighCreditAccount : public NormalAccount
{
private:
	int specialRate;
public:
	HighCreditAccount(int ID, int money, char * name, int rate, int special)
		: NormalAccount(ID, money, name, rate), specialRate(special)
	{  }	
	virtual void Deposit(int money)
	{
		NormalAccount::Deposit(money);        // 원금과 이자추가 
		Account::Deposit(money*(specialRate/100.0));   // 특별이자추가
	}
};
#endif

> NormalAccount 클래스의 상속을 받은 HighCreditAccount 클래스임

> virtual 선언은 위와 같은 이유로 되었음

 

<AccountHandler.h>

// AccountHandler.h
#ifndef __ACCOUN_HANDLER_H__
#define __ACCOUN_HANDLER_H__

#include "Account.h"

class AccountHandler
{
private:
	Account * accArr[100];
	int accNum;
public:
	AccountHandler();
	void ShowMenu(void) const;
	void MakeAccount(void);
	void DepositMoney(void);
	void WithdrawMoney(void);
	void ShowAllAccInfo(void) const;
	~AccountHandler();
protected:
	void MakeNormalAccount(void);
	void MakeCreditAccount(void);
};
#endif

 

<AccountHandler.cpp>

// AccountHandler.cpp
#include "BankingCommonDecl.h"
#include "AccountHandler.h"
#include "Account.h"
#include "NormalAccount.h"
#include "HighCreditAccount.h"

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

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

void AccountHandler::MakeNormalAccount(void)
{
	int id;
	char name[NAME_LEN];
	int balance;
	int interRate;

	cout<<"[보통예금계좌 개설]"<<endl;
	cout<<"계좌ID: ";	cin>>id;
	cout<<"이  름: ";	cin>>name;
	cout<<"입금액: ";	cin>>balance;
	cout<<"이자율: ";	cin>>interRate;
	cout<<endl;

	accArr[accNum++]=new NormalAccount(id, balance, name, interRate);
}

void AccountHandler::MakeCreditAccount(void)
{
	int id;
	char name[NAME_LEN];
	int balance;
	int interRate;
	int creditLevel;

	cout<<"[신용신뢰계좌 개설]"<<endl;
	cout<<"계좌ID: ";	cin>>id;
	cout<<"이  름: ";	cin>>name;
	cout<<"입금액: ";	cin>>balance;
	cout<<"이자율: ";	cin>>interRate;
	cout<<"신용등급(1toA, 2toB, 3toC): ";	cin>>creditLevel;
	cout<<endl;

	switch(creditLevel)
	{
	case 1:
		accArr[accNum++]=new HighCreditAccount(id, balance, name, interRate, LEVEL_A);
		break;
	case 2:
		accArr[accNum++]=new HighCreditAccount(id, balance, name, interRate, LEVEL_B);
		break;
	case 3:
		accArr[accNum++]=new HighCreditAccount(id, balance, name, interRate, LEVEL_C);
	}
}

void AccountHandler::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 AccountHandler::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;
}

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

void AccountHandler::ShowAllAccInfo(void) 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];
}

> AccountHandler은 데이터 클래스를 활용해서 실제 데이터들을 관리할 수 있는 기능을 가진 기능적 클래스임

> protected 선언이 된 멤버함수 MakeNormalAccount, MakeCreditAccount의 경우는 public 멤버함수인 MakeAccount로만 접근을 할 수 있도록 하는 의도를 가짐과 동시에 상속에 의한 확장성도 고려한 것으로 보임

​

<BankingCoomnDecl.h>

// BankingCommonDecl.h
#ifndef __BANKING_COMMON_H__
#define __BANKING_COMMON_H__

#include <iostream>
#include <cstring>

using namespace std;
const int NAME_LEN=20;

// 프로그램 사용자의 선택 메뉴
enum {MAKE=1, DEPOSIT, WITHDRAW, INQUIRE, EXIT};

// 신용등급
enum {LEVEL_A=7, LEVEL_B=4, LEVEL_C=2};

// 계좌의 종류
enum {NORMAL=1, CREDIT=2};

#endif

> C++ 표준 라이브러리와 열거형(enum)을 선언함

 

<BankingSystemMain.cpp>

// BankingSystemMain.cpp
#include "BankingCommonDecl.h"
#include "AccountHandler.h"

int main(void)
{
	AccountHandler manager;
	int choice;
	
	while(1)
	{
		manager.ShowMenu();
		cout<<"선택: "; 
		cin>>choice;
		cout<<endl;
		
		switch(choice)
		{
		case MAKE:
			manager.MakeAccount(); 
			break;
		case DEPOSIT:
			manager.DepositMoney(); 
			break;
		case WITHDRAW: 
			manager.WithdrawMoney(); 
			break;
		case INQUIRE:
			manager.ShowAllAccInfo(); 
			break;
		case EXIT:
			return 0;
		default:
			cout<<"Illegal selection.."<<endl;
		}
	}
	return 0;
}

 

<Makefile>

CC = g++

CFLAGS = -Wall -g -I/usr/include/mysql
LDFLAGS = -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -Wl, -rpath,/usr/lib/x86_64-linux-gnu

SRCS = BankingSystemMain.cpp AccountHandler.cpp Account.cpp
OBJS = $(SRCS: .cpp= .o)
Target = myprogram

all: $(Target)

$(Target): $(OBJS)
	$(CC) $(OBJS) -o $@

%.o: %.cpp
	$(CC) $(CFLAGS) -c $< -o $@
clean:
	rm -f $(Target) *.o

'LMS 7 > 개발일지' 카테고리의 다른 글

25.08.07 학습개발일지 / QT6 Chapter05(2)  (2) 2025.08.11
25.08.06 학습개발일지 / QT6 Chapter 05(1)  (2) 2025.08.10
25.08.02 학습개발일지 / C++ Study 6(1)  (0) 2025.08.02
25.08.01 학습개발일지 C++ Study5  (2) 2025.08.01
25.07.31 학습개발일지 C++ Study5  (11) 2025.07.31
'LMS 7/개발일지' 카테고리의 다른 글
  • 25.08.07 학습개발일지 / QT6 Chapter05(2)
  • 25.08.06 학습개발일지 / QT6 Chapter 05(1)
  • 25.08.02 학습개발일지 / C++ Study 6(1)
  • 25.08.01 학습개발일지 C++ Study5
m_Dev
m_Dev
  • m_Dev
    m_Dev
    m_Dev
  • 전체
    오늘
    어제
    • 분류 전체보기
      • MAIN STUDY
        • 정보보안
        • 빅데이터
        • 정보처리
        • 컴퓨터 구조
        • 기타
      • JOB
        • Study
        • Project
      • LMS 7
        • 개발일지
      • FRAMEWORK
        • Qt
        • MFC
        • Winform
        • WPF
        • MAUI
      • NETWORK
        • Study
        • Assignment
      • PYTHON
        • Set
        • Study
        • Assignment
        • Project
      • C
        • Set
        • Study
        • Assignment
        • Project
      • C++
        • Set
        • Study
        • Assignment
        • Project
      • C#
        • Set
        • Study
        • Assignment
        • Project
      • DATABASE
        • MySQL
        • SQLite
      • IDE
        • VisualStudioCode
        • VisualStudio
        • Pycharm
        • Colab
      • 기타
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
m_Dev
25.08.04 학습개발일지 / C++ Study6(2)
상단으로

티스토리툴바