考虑以下代码(也可在 C++ Shell 获得)。
基本上,我们有一个带有 FullTime 和 PartTime 子类的 Employee 基类。组织类有一个员工列表(可以是全职或兼职)。
当我想在 Organization 类中定义一个 getEmployee(int) 方法时,问题就出现了。它应该返回什么类型的员工?如果它返回一个 Employee*:
- 首先,返回一个指针安全吗?我假设它的地址是永久性的,因为它将发送 empList 中该元素的地址。对吧?
- 当我将 Employee* 转换为 FullTimeEmployee* 时,显然我丢失了成绩字段。我该如何解决这个问题?
根据答案Here ,如果我需要知道“一个对象是什么类,这通常表明存在设计缺陷......”。这里也是这样吗?
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
class Employee {
public:
int getId() { return id;}
void setId( int id) {this->id = id;}
protected:
int id;
};
class PartTimeEmployee : public Employee {
};
class FullTimeEmployee : public Employee {
public:
int getGrade() {return grade;}
void setGrade(int grade) {this->grade = grade;}
private:
int grade;
};
class Organization {
public:
void addEmployee(Employee& e) { empList.push_back(e); }
Employee* getEmployee(int id) {
for (std::list<Employee>::iterator it=empList.begin(); it!=empList.end(); ++it) {
if(it->getId() == id) {return &(*it);}
}
return NULL;
}
private:
std::list<Employee> empList;
};
int main()
{
Employee e1;
e1.setId(5);
FullTimeEmployee *pFt1 = (FullTimeEmployee*) &e1;
pFt1->setGrade(1);
Organization org1;
org1.addEmployee(*pFt1);
FullTimeEmployee *pFt2 = (FullTimeEmployee*) org1.getEmployee(5);
cout << pFt2->getId() << endl;
cout << pFt2->getGrade() << endl;
}
最佳答案
first of all, is it safe to return a pointer?
是的。该对象在一个列表中,因此指向它的指针和引用在它被删除之前一直有效。
When I cast
Employee*
to aFullTimeEmployee*
, obviuosly I lose the grade field.
在那之前你已经失去了它 - 当你转换为 Employee
将它放入列表中时。如果要存储不同类型的对象(具有公共(public)基类),则必须存储指针,并调整 addEmployee
以允许存储子类型。然后你可以在检索指针后使用 RTTI 来区分类型。
请记住管理对象的生命周期(可能使用智能指针),并且您可能需要为基类提供一个虚拟析构函数(用于正确删除和启用 RTTI)。
if I need to know "what class an object is, that usually indicates a design flaw...". Is it also the case here?
这是一个见仁见智的问题,但我会说是的。在我看来,添加一个属性(或者可能是“等级”的特殊值)来指示就业状态比处理继承及其所有相关并发症要简单得多。
关于c++ - 具有关系的对象类型 - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30510322/