我希望从下面的向量中输出每个对象的内容。
vector<Employees*> midzer;
我找到的“解决方案”是执行以下操作:
for (vector<Employees*>::iterator i = midzer.begin(); i != midzer.end(); ++i)
{
cout <<
(*i)->getFirstName() << " " << // Base class method.
(*i)->getLastName() << "\n" << // Base class method.
(*i)->getSalary() << "\n" << // Base class method.
(*i)->getNumMeetings() << "\n" << // Derived class method.
(*i)->getNumVacationDays() << endl; //Derived class method.
}
问题是我收到一条错误,指出getNumMeetings和getNumVacationDays不是Employees(基类)的成员。
任何人都可以详细说明为什么迭代器不能“看到”派生方法,并且如果可能的话为它提供解决方案?
任务是创建一个员工“数据库”,其功能是动态创建和删除不同类型的员工,并输出格式良好的整个数据库。
其他信息:
/肯尼斯
答案 0 :(得分:2)
您不能查看基类成员,因为他们不。您必须转换为派生类型使用其成员:
dynamic_cast<Manager*>(*i)->getNumMeetings() << "\n" <<
但更好(更多OO)的方法是使用类层次结构来解决问题 - 在基类中放置一个虚拟的 write 方法,然后在派生类中对其进行专门化。
答案 1 :(得分:0)
任何人都可以详细说明为什么迭代器不能“看到”派生方法
编译不知道虚函数调用,因此这些函数必须存在Employees
(更好地命名为Employee
,当然?)。
如果您要使用虚拟分派,则必须在基类中声明所有这些成员函数。如果它们特定于派生类,那么您的设计就会被破坏!
答案 2 :(得分:0)
使用多态?
定义虚拟成员打印功能,使用ostream。叫它。 将派生类版本调用基类版本,然后打印其额外信息。
答案 3 :(得分:0)
我们称之为Liskov替换原则,实际上意味着你的循环应该是任何类型员工的有效代码。
如果您知道类型是Managers,那么您确实有一个指向manager的指针向量。
您可能正在寻找的是一个抽象的打印功能。
class Employee
{
public:
virtual ~Employee();
virtual std::ostream& print( std::ostream & ) const = 0;
};
class Manager : public Employee
{
public:
virtual std::ostream& print( std::ostream & ) const;
};
std::ostream& Manager::print( std::ostream & os ) const
{
// print, knowing I am a Manager
return os;
}
for (vector<Employees*>::iterator i = midzer.begin(); i != midzer.end(); ++i)
{
(*i)->print( std::cout );
}
如果您实际上始终在单个向量中始终使用相同的类型,则可以考虑更改模型以反映这些聚合。管理者的向量不是员工的一种向量,也不是反过来的。
答案 4 :(得分:0)
这只适用于相反的方向。因此派生类型可以“看到”其基类型的成员(因为它是基类型),但基类型无法看到派生类型的成员(因为它是不派生类型。)
解决方案是在基类 Employee 中实现诸如“print”或“display”之类的函数,然后在每个派生类中重写它。
答案 5 :(得分:0)
问题不在于迭代器,而在于您构建类的方式。
目前尚不清楚如何定义Employee类和子类。在面向对象设计中,基类包含接口,子类或具体类可以覆盖/实现特定行为。这称为program to interface原则。利用虚函数来做到这一点。