[열혈 C++] Chap08 연습문제
08-1 [상속 관계의 확장과 추상클래스]
- 코드💻
/*
* 위험수당을 지급하는 ForeignSalesWorker 클래스를 정의하여 확장해보자
* 위험수당은 위험의 노출도에 따라서 나뉘고, 한번 결정된 직원의 위험 노출도는 변경되지 않는다
* Employee클래스는 추상클래스로 정의한다
*/
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
namespace RISK_LEVEL{
enum
{
RISK_A, RISK_B, RISK_C
};
double RiskRatio(int risk) {
switch (risk)
{
case RISK_A:
return 0.3;
break;
case RISK_B:
return 0.2;
break;
case RISK_C:
return 0.1;
break;
default:
break;
}
}
}
class Employee
{
private:
char name[100];
public:
Employee(const char* name)
{
strcpy(this->name, name);
}
void ShowYourName() const
{
cout << "name: " << name << endl;
}
virtual int GetPay() const = "0";
virtual void ShowSalaryInfo() const ="0";
};
class PermanentWorker : public Employee
{
private:
int salary;
public:
PermanentWorker(const char* name, int money)
: Employee(name), salary(money)
{ }
int GetPay() const
{
return salary;
}
void ShowSalaryInfo() const
{
ShowYourName();
cout << "salary: " << GetPay() << endl << endl;
}
};
class SalesWorker : public PermanentWorker
{
private:
int salesResult; // 월 판매실적
double bonusRatio; // 상여금 비율
public:
SalesWorker(const char* name, int money, double ratio)
: PermanentWorker(name, money), salesResult(0), bonusRatio(ratio)
{ }
void AddSalesResult(int value)
{
salesResult += value;
}
int GetPay() const
{
return PermanentWorker::GetPay()
+ (int)(salesResult * bonusRatio);
}
void ShowSalaryInfo() const
{
ShowYourName();
cout << "salary: " << GetPay() << endl << endl;
}
};
class ForeignSalesWorker : public SalesWorker
{
public:
ForeignSalesWorker(const char* name, int money, double ratio, int risk);
~ForeignSalesWorker();
private:
const int m_eRisk; //위험노출도
public:
int GetPay() const;
int RiskPay() const;
void ShowSalaryInfo() const;
};
ForeignSalesWorker::ForeignSalesWorker(const char* name, int money, double ratio, int risk)
: SalesWorker(name, money, ratio), m_eRisk(risk)
{ }
ForeignSalesWorker::~ForeignSalesWorker()
{ }
int ForeignSalesWorker::GetPay() const
{
return SalesWorker::GetPay() + RiskPay();
}
int ForeignSalesWorker::RiskPay() const {
return SalesWorker::GetPay() * RISK_LEVEL::RiskRatio(m_eRisk);
}
void ForeignSalesWorker::ShowSalaryInfo() const
{
ShowYourName();
cout << "salary: " << SalesWorker::GetPay() << endl;
cout << "risk pay: " << RiskPay() << endl;
cout << "sum: " << GetPay() << endl << endl;
}
class EmployeeHandler
{
private:
Employee* empList[50];
int empNum;
public:
EmployeeHandler() : empNum(0)
{ }
void AddEmployee(Employee* emp)
{
empList[empNum++] = emp;
}
void ShowAllSalaryInfo() const
{
for (int i = 0; i < empNum; i++)
empList[i]->ShowSalaryInfo();
}
void ShowTotalSalary() const
{
int sum = 0;
for (int i = 0; i < empNum; i++)
sum += empList[i]->GetPay();
cout << "salary sum: " << sum << endl;
}
~EmployeeHandler()
{
for (int i = 0; i < empNum; i++)
delete empList[i];
}
};
int main(void) {
//회사 직원 급여 책임지는 곳이라 할 수 있음
EmployeeHandler handler;
//해외 영업자 등록
ForeignSalesWorker* fseller1 = new ForeignSalesWorker("Hong", 1000, 0.1, RISK_LEVEL::RISK_A);
fseller1->AddSalesResult(7000); //영업실적
handler.AddEmployee(fseller1);
ForeignSalesWorker* fseller2 = new ForeignSalesWorker("Yoon", 1000, 0.1, RISK_LEVEL::RISK_B);
fseller2->AddSalesResult(7000);
handler.AddEmployee(fseller2);
ForeignSalesWorker* fseller3 = new ForeignSalesWorker("Lee", 1000, 0.1, RISK_LEVEL::RISK_C);
fseller3->AddSalesResult(7000);
handler.AddEmployee(fseller3);
//이번달 지급해야할 급여 정보
handler.ShowAllSalaryInfo();
return 0;
}
-
해외영업사원도 영업사원이므로
SalesWorker
클래스를 상속받도록 했다. -
상속은 잘만 활용한다면 코드의 확장성 부분에 아주 좋은 것 같다. 그러기 위해선 높은 클래스(기초클래스)일수록 멤버 변수와 함수가 어느 정도 범위의 범용성을 갖게 할지 잘 정해야 할 것 같은데 쉬울 것 같진 않다.
-
동시에 클래스는 유도클래스를 생각해보았을 때, 당장 필요한 것만으로 채울 수도 없는 것 같다. 어떤 기능과 변수가 필요할지, 어디까지 정의해놓는 것이 좋을 지, 포함관계를 고려하여 최적화 시키고 나중에 수정할 이유를 줄이도록 해야할 것 같다.