这是更好的方法来检查对象类型 [英] which is the better approach to check object type

查看:94
本文介绍了这是更好的方法来检查对象类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

方法:1

  class Employee 
{
public:
virtual int calculateSalary ()= 0;

};

类PermanentEmployee:public Employee {
const int salaryPerMonth;
public:
PermanentEmployee(int sal):salaryPerMonth(sal){}

int calculateSalary(){
return salaryPerMonth;
}
};

class ContractEmployee:public Employee {
const int wagesPerHr;
int totalHour;
public:
ContractEmployee(int sal):wagesPerHr(sal),totalHour(0){}

void setWorkingDuration(int time){
totalHour = totalHour +时间;
}
int calculateSalary(){
return wagesPerHr * totalHour;
}
};

类经理{
list< Employee *> ls;
public:
void assignWorkingHour(){
list< Employee *> :: iterator it;

for(it = ls.begin(); it!= ls.end(); it ++){
Employee * emp = * it;
ContractEmployee * contractEmp = dynamic_cast< ContractEmployee *>(emp);
if(contractEmp){
contractEmp-> setWorkingDuration(5);
}
}
}
};

在问题中,有两种类型的Employee:PermanentEmployee和ContractEmployee。
有一个名为Manager的类,其中包含在他下工作的所有员工的列表。
对于ContractEmployee,它必须调用setWorkingDuration函数,该函数在类Manager中的方法assignWorkingHour中调用。



问题是:
of Employee由dynamic_cast运算符确定,并且Manager必须知道Employee的所有类型的派生类



approach2:在Employee类中添加另一个成员

 枚举TypeOfEmployee {CONTRACT,PERMANENT}; 

并检查TypeOfEmployee以确定Employee类型


解决方案

更好的方法是编写代码, t需要有关确切对象类型的知识。对我来说,最优雅的方式是将 setWorkingDuration()移动到employee类。可能这样:

  class Employee 
{
public:
//计算工资为这个雇员。
//返回计算的薪水。
virtual int calculateSalary()= 0;
//设置工作持续时间。如果员工是永久的,什么也不做。
//如果Employee在合同上则返回true,如果为永久则返回false。
virtual bool setWorkingDuration(int time)
{
return false;
}
};

类PermanentEmployee:public Employee
{
const int salaryPerMonth;
public:
PermanentEmployee(int sal):salaryPerMonth(sal){}

int calculateSalary()
{
return salaryPerMonth;
}
};

class ContractEmployee:public Employee
{
const int wagesPerHr;
int totalHour;
public:
ContractEmployee(int sal):wagesPerHr(sal),totalHour(0){}

int calculateSalary()
{
return wagesPerHr * totalHour;
}

bool setWorkingDuration(int time)
{
totalHour = totalHour + time;
return true;
}
};

class Manager
{
list< Employee *> ls;
public:
void assignWorkingHours()
{
list< Employee *> :: iterator it;
for(it = ls.begin(); it!= ls.end(); it ++)
{
Employee * emp = * it;
emp-> setWorkingDuration(5);
}
}
};


不得不知道 Employee 实际上是 PermanentEmployee 还是 ContractEmployee 。这就是多态性给你。一般来说,如果你必须使用 dynamic_cast<> ,你可能想再看看设计,看看你是否可以省略它。


Approach :1

class Employee 
{
public:
    virtual int calculateSalary() = 0;

};

class PermanentEmployee : public Employee {
    const int salaryPerMonth;
public:
    PermanentEmployee(int sal) : salaryPerMonth(sal){}

    int calculateSalary() {
        return salaryPerMonth;
    }
};

class ContractEmployee : public Employee {
    const int wagesPerHr;
    int totalHour;
public:
    ContractEmployee(int sal) : wagesPerHr(sal), totalHour(0){}

    void setWorkingDuration(int time) {
        totalHour = totalHour + time;
    }
    int calculateSalary() {
        return wagesPerHr * totalHour;
    }
};

class Manager {
    list<Employee *> ls;
public:
    void assignWorkingHour() {
        list<Employee *>::iterator it;

        for(it = ls.begin(); it != ls.end(); it++) {
            Employee *emp = *it;
            ContractEmployee* contractEmp = dynamic_cast<ContractEmployee* >(emp);
            if(contractEmp) {
                contractEmp->setWorkingDuration(5);
            }
        }
    }
};

In problem, there are 2 type of Employee : PermanentEmployee and ContractEmployee. There is a class called Manager which contains a list of all employee working under him. For ContractEmployee, it has to invoke function setWorkingDuration, which is being invoked in method assignWorkingHour of class Manager.

The problem is: Here type of Employee is being determind by dynamic_cast operator and Manager has to know about all type of derive class of Employee

approach2: add another member in class Employee

       enum TypeOfEmployee {CONTRACT, PERMANENT};

and check TypeOfEmployee to determine the type of Employee

Please tell which is better or Is there any alternative approach?

解决方案

The better approach is to write code that doesn't require knowledge about the exact object type. Seems to me the most elegant way to deal with this is to move the setWorkingDuration() to the employee class. Probably like this:

class Employee
{
public:
    // Calculates the salary for this employee.
    // Returns the calculated salary.
    virtual int calculateSalary() = 0;
    // Sets the working duration. Does nothing if the employee is permanent.
    // Returns true if Employee is on a contract, false if permanent.
    virtual bool setWorkingDuration(int time)
    {
        return false;
    }
};

class PermanentEmployee : public Employee
{
    const int salaryPerMonth;
public:
    PermanentEmployee(int sal) : salaryPerMonth(sal) {}

    int calculateSalary()
    {
        return salaryPerMonth;
    }
};

class ContractEmployee : public Employee
{
    const int wagesPerHr;
    int totalHour;
public:
    ContractEmployee(int sal) : wagesPerHr(sal), totalHour(0) {}

    int calculateSalary()
    {
        return wagesPerHr * totalHour;
    }

    bool setWorkingDuration(int time)
    {
        totalHour = totalHour + time;
        return true;
    }
};

class Manager
{
    list<Employee *> ls;
public:
    void assignWorkingHours()
    {
        list<Employee *>::iterator it;
        for(it = ls.begin(); it != ls.end(); it++)
        {
            Employee* emp = *it;
            emp->setWorkingDuration(5);
        }
    }
};

This way, the Manager class doesn't have to know whether the Employee is actually a PermanentEmployee or a ContractEmployee. That is what polymorphism gives you. Generally speaking if you have to use dynamic_cast<>, you may want to take another look at the design and see if you can omit it.

这篇关于这是更好的方法来检查对象类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆