使用第一层指针调用第三层子类
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);
}
}
两件事!
- 当您创建一个新的派生 class 对象时,在本例中为
AdminStaff
或 TeachingStaff
,您不必类型转换回基类来调用派生 class方法。
因此,
ptr[i] = new TeachingStaff;
(( TeachingStaff*)ptr[i])->setTeaching(16);
你可以这样写,
TeachingStaff *ts = ptr[i] = new TeachingStaff;
ts->setTeaching(16);
- 您应该只调用基础 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);
}
}
我创建了一个 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);
}
}
两件事!
- 当您创建一个新的派生 class 对象时,在本例中为
AdminStaff
或TeachingStaff
,您不必类型转换回基类来调用派生 class方法。
因此,
ptr[i] = new TeachingStaff;
(( TeachingStaff*)ptr[i])->setTeaching(16);
你可以这样写,
TeachingStaff *ts = ptr[i] = new TeachingStaff;
ts->setTeaching(16);
- 您应该只调用基础 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);
}
}