C++ 상속 관계의 확장과 추상 클래스
문제
예제 EmployeeManager4.cpp를 확장하여 다음 특성에 해당하는 ForeignSalesWorker 클래스를 추가로 정의해보자.
“영업직 직원 중 일부는 오지산간으로 시장개척을 진행하고 있다. 일부는 아마존에서, 또 일부는 테러의 위험이 있는 지역에서 영업활동을 진행 중에 있다. 따라서 이러한 직원들을 대상으로 별도의 위험수당을 지급하고자 한다.”
위험수당의 지급방식은 ‘위험의 노출도’ 에 따라서 다음과 같이 나뉘며, 한번 결정된 직원의 ‘위험 노출도’ 는 변경되지 않는다고 가정한다(이는 const 멤버변수의 선언을 유도하는 것이다).
- 리스크 A: 영업직의 기본급여와 인센티브 합계 총액의 30%를 추가로 지급한다.
- 리스크 B: 영업직의 기본급여와 인센티브 합계 총액의 20%를 추가로 지급한다.
- 리스크 C: 영업직의 기본급여와 인센티브 합계 총액의 10%를 추가로 지급한다.
다음 main 함수와 함께 동작하도록 ForeignSalesWorker 클래스를 정의하기 바라며, Employee 클래스는 객체 생성이 불가능한 추상 클래스로 정의하기 바란다.
main 함수
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;
}
위의 main 함수에서 보이는 RISK_LEVEL 이름공간의 RISK_A, RISK_B, RISK_C는 enum형으로 선언된 상수이다. 그럼 이어서 실행결과를 보이겠다.
실행의 예

위의 실행결과에서 salary 내역은 일반 영업직 직원의 급여 계산결과이며(기본금에 상여금을 더한 결과), risk pay가 위험수당에 속한다.
EmployeeManager4.cpp 코드
#include <iostream>
#include <cstring>
using namespace std;
class Employee
{
private:
    char name[100];
public:
    Employee(char* name)
    {
        strcpy(this->name, name);
    }
    void ShowYourName() const
    {
        cout<<"name: "<<name<<endl;
    }
    virtual int GetPay() const
    {
        return 0;
    }
    virtual void ShowSalaryInfo() const {}
};
class TemporaryWorker : public Employee
{
private:
    int workTime;
    int payPerHour;
public:
    TemporaryWorker(char* name, int pay) : Employee(name), workTime(0), payPerHour(pay) {}
    void AddWorkTime(int time)
    {
        workTime += time;
    }
    int GetPay() const
    {
        return workTime*payPerHour;
    }
    void ShowSalaryInfo() const
    {
        ShowYourName();
        cout<<"salary: "<<GetPay()<<endl<<endl;
    }
};
class PermanentWorker: public Employee
{
private:
    int salary;
public:
    PermanentWorker(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(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 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;
    handler.AddEmployee(new PermanentWorker("KIM", 1000));
    handler.AddEmployee(new PermanentWorker("LEE", 1500));
    TemporaryWorker * alba = new TemporaryWorker("Jung", 700);
    alba->AddWorkTime(5);
    handler.AddEmployee(alba);
    SalesWorker * seller = new SalesWorker("Hong", 1000, 0.1);
    seller->AddSalesResult(7000);
    handler.AddEmployee(seller);
    handler.ShowAllSalaryInfo();
    handler.ShowTotalSalary();
    return 0;
}
풀이 코드
#include <iostream>
#include <cstring>
using namespace std;
namespace RISK_LEVEL
{
    enum
    {
        RISK_A,
        RISK_B,
        RISK_C
    };
}
class Employee
{
private:
    char name[100];
public:
    Employee(char* name)
    {
        strcpy(this->name, name);
    }
    void ShowYourName() const
    {
        cout<<"name: "<<name<<endl;
    }
    virtual int GetPay() const = 0;
    virtual void ShowSalaryInfo() const = 0;
};
class TemporaryWorker : public Employee
{
private:
    int workTime;
    int payPerHour;
public:
    TemporaryWorker(char* name, int pay) : Employee(name), workTime(0), payPerHour(pay) {}
    void AddWorkTime(int time)
    {
        workTime += time;
    }
    int GetPay() const
    {
        return workTime*payPerHour;
    }
    void ShowSalaryInfo() const
    {
        ShowYourName();
        cout<<"salary: "<<GetPay()<<endl<<endl;
    }
};
class PermanentWorker: public Employee
{
private:
    int salary;
public:
    PermanentWorker(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(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
{
private:
    const int risk;
public:
    ForeignSalesWorker(char* name, int money, double ratio, int risk) : SalesWorker(name, money, ratio), risk(risk) {}
    int GetPay() const
    {
        switch(risk)
        {
            case 0:
                return SalesWorker::GetPay() * 0.3;
                break;
            case 1:
                return SalesWorker::GetPay() * 0.2;
                break;
                
            case 2:
                return SalesWorker::GetPay() * 0.1;
                break;
            default:
                return 0;
        }
    }
    void ShowSalaryInfo() const
    {
        ShowYourName();
        cout<<"salary: "<<SalesWorker::GetPay()<<endl;
        cout<<"risk pay: "<<GetPay()<<endl;
        cout<<"sum: "<<SalesWorker::GetPay()+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;
}
댓글남기기