我有一个链表类(List),它只处理Node类型的对象。它可以用这些节点做各种各样的事情,假设它们正确地重载了布尔比较。问题是,我想将这个List类与一种称为Term的特殊节点(一个带有系数和指数或度数的代数项)一起使用。如何告诉我的List类使用Term函数(Term有Print()函数和比较运算符的特殊版本),即使它使用节点指针处理条款?例如,我的Print()类似于:
Node* walker=head;
while(walker)
{
walker->Print();
walker=walker->next;
}
除了没有Node :: Print()之外,我希望它调用Term :: Print()!我是否必须创建一个全新的List类来处理Term类对象?
答案 0 :(得分:1)
这是多态性的典型例子。您可以像在WhozCraig建议的那样向Node类添加一个Print()函数。 (请阅读C ++中的虚函数和抽象类。)您可以使Print()成为虚函数。您可以决定是否要将Print()设为纯虚函数。如果它是纯虚函数,它将在基类中声明为这样。
class Node{
virtual void Print() = 0;
// If you don't want this to be pure virtual
// You can give a generic definition
}
在这种情况下,由于您没有在基类中定义Print(),因此每个派生类都不是抽象的,必须实现此方法。因此,Term类可以从Node类派生并相应地实现它的Print()方法:)并且您可以使用基类指针来调用此函数。如果您将来决定继承Node并添加不同的Print()实现,则根本不需要更改Node:)
希望这有帮助!
答案 1 :(得分:0)
您已经偏离了通常的列表设计 - 建议使用模板而不是从Node
类派生。然后,您需要一个foreach
方法,该方法将在每个节点上执行操作,在本例中为print
。强烈建议使用C ++标准库容器,而不是编写所有这些“原始”。
另一种选择(标准较少且设计缺陷较少)是派生PrintList
来调用Print
函数,并且需要模板化或以{ {1}}节点作为编译器将期望此函数。
答案 2 :(得分:0)
三种选择: -
在现实世界中,您将使用std::list或类似的容器类
或者,您可以将Print()作为虚拟方法添加到Node,(并使其成为抽象的,可能)
class Node {
...
virtual void Print() = 0;
}
或者,您可以使用将节点*转换为Term *
Term *t = boost::polymorphic_cast<Term*>(walker);
t->Print();