使用第一层指针调用第三层子类

Calling a 3rd layer subclass using a 1st layer pointer

我创建了一个 class 层次结构,其中第一层超级 class 是员工。在我的第二层,我有 2 个子classes,分别称为管理人员和学术人员。 (这两层也是抽象的classes)。学术人员还有 2 个子classes 仅教学和研究。

在我的主要工作中,我正在尝试创建一个包含 10 个教职员工指针(5 个管理员和 5 个学术人员)的数组,并使用这些指针操作第 3 层子 classes。 请记住,第 3 层 subclasses 具有在第 1 层或第 2 层中不存在的行为。因此,我必须使用类型转换。 我可以单独更改我的第 3 层行为,例如

((ResearchStaff *)ptr[i])->setResearchHour(23);

但它很快就会变得非常混乱。 我的问题是,如何在 for 或 while 循环中访问我的第 3 层行为,而不必单独设置它们。这是我与之合作的主要对象。非常感谢!!

int main()
{
  Staff *ptr[10];
  for(int i=0;i<10;i++)
  {
    ptr[i] = new AdminStaff;
    ((AdminStaff *)ptr[i])->setAdmin(12);

    i++;
    ptr[i] = new TeachingStaff;
    (( TeachingStaff*)ptr[i])->setTeaching(16);
  }
}

两件事!

  1. 当您创建一个新的派生 class 对象时,在本例中为 AdminStaffTeachingStaff,您不必类型转换回基类来调用派生 class方法。

因此,

    ptr[i] = new TeachingStaff;
    (( TeachingStaff*)ptr[i])->setTeaching(16);

你可以这样写,

    TeachingStaff *ts = ptr[i] = new TeachingStaff;
    ts->setTeaching(16);
  1. 您应该只调用基础 class 引用/指针来调用所有 classes 共有的方法。

最后,如果这些 class 没有很多共同的属性,您可以考虑 composition 作为替代设计策略,而不是使用多重继承。

您可以使用 Visitor 模式。

向您的 Staff class 添加一个名为 accept 的方法,如下所示:

class Staff 
{
   //Other staff stuff
   public:
      void accept(const Visitor& v) = 0;
}

将实现添加到您的叶子 classes...

class ResearchTeacher
{
    //Other research teacher stuff...

    public:
       void accept(const Visitor& v) {
       v.visit(*this);
    }
}

然后定义一个知道如何处理每种类型的访客:

class Visitor
{
   public:
      void visit(ResearchTeacher& teacher) 
      {
         teacher.setResearch(16);
      }

      void visit(TeachingTeacher& teacher)
      {
         teacher.setTeaching(16);
      }

      void visit(AdminStaff& admin) 
      {
         admin.setAdmin(12);
      }
}

现在调用代码不用担心了:

int main()
{
  Visitor v;
  Staff *ptr[10];
  for(int i=0;i<10;i++)
  {
    ptr[i] = new AdminStaff;
    ptr[i]->accept(v);

    i++;
    ptr[i] = new TeachingStaff;
    ptr[i]->accept(v);
  }
}