方法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);
}
}
}
};
在问题中,有两种类型的Employee:PermanentEmployee和ContractEmployee.
有一个名为Manager的类,其中包含在他下工作的所有员工的列表.
对于ContractEmployee,它必须调用函数setWorkingDuration(),该函数在类Manager的方法assignWorkingHour中调用.
问题是:
这里的Employee类型由dynamic_cast运算符确定,Manager必须知道Employee的所有类型的派生类.
方法2:
在类Employee中添加另一个成员:
enum TypeOfEmployee {CONTRACT,PERMANENT};
并检查TypeOfEmployee以确定Employee的类型
请告诉我哪个更好或有替代方法吗?
解决方法
更好的方法是编写不需要确切对象类型知识的代码.在我看来,处理这个问题最优雅的方法是将setWorkingDuration()移动到employee类.可能是这样的:
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);
}
}
};
这样,Manager类不必知道Employee实际上是PermanentEmployee还是ContractEmployee.这就是多态性给你的东西.一般来说,如果您必须使用dynamic_cast<>,您可能需要再次查看设计并查看是否可以省略它.