方法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<>,您可能需要再次查看设计并查看是否可以省略它.