迭代器无法访问派生类的成员方法

Iterator can't access derived class' member methods

本文关键字:成员方法 派生 访问 迭代器      更新时间:2023-10-16

我希望从下面的向量中输出每个对象的内容。

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(基类)的成员。

有人能详细说明迭代器为什么不能"看到"派生的方法吗?如果可能的话,能提供一个解决方案吗?

任务是创建一个员工"数据库",该数据库具有动态创建和删除不同类型员工的功能,并输出格式良好的整个数据库。

附加信息:

  • 我只能创建一个矢量
  • 我必须创建一个基类和三个派生类(经理、工程师和研究员)

/Kenneth

您不能查看基类成员,因为它们不在那里。您必须转换为派生类型才能使用其成员:

dynamic_cast<Manager*>(*i)->getNumMeetings() << "n" <<

但更好(更OO)的方法是使用类层次结构来解决问题——在基类中放置一个虚拟的write方法,然后将其专门用于派生类。

有人能详细说明为什么迭代器不能"看到"派生方法吗

编译不知道虚拟函数调用,所以这些函数必须存在于Employees中(当然,更好的名称是Employee?)。

如果要使用虚拟调度,那么所有这些成员函数都必须在基类中声明。如果它们是特定于派生类的,那么您的设计就被破坏了!

使用多态性?

定义一个虚拟成员打印函数,使用一个ostream。叫它吧。让派生类版本调用基类版本,然后打印它们的额外信息。

这就是我们所说的Liskov替换原则,它实际上意味着您的循环应该是任何类型的Employees的有效代码。

若你们知道这些类型是经理,那个么你们真的有一个指向经理的指针向量。

您可能想要的是一个抽象的打印函数。

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 );
}

如果你实际上总是在一个向量中,总是有相同的类型,你可能会考虑改变你的模型来反映这些聚合。经理的矢量不是员工的矢量,也不是相反。

这只能在相反的方向上起作用。因此,派生类型可以"看到"其基类型的成员(因为它基类型),但基类型不能看到派生类型的成员。

解决方案是在基类Employee中实现一个函数,如"print"或"display",然后在每个派生类中重写它。

问题不在于迭代器,而在于类的结构化方式。

目前还不清楚您是如何定义Employee类和子类的。在面向对象设计中,基类包含接口,子类或具体类可以覆盖/实现特定的行为。这被称为程序到接口原理。使用虚拟函数来完成此操作。