C++ 상속 관계의 확장과 추상 클래스

3 분 소요

문제

예제 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형으로 선언된 상수이다. 그럼 이어서 실행결과를 보이겠다.

실행의 예

Example

위의 실행결과에서 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;
}

댓글남기기