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