1

我有一个仅处理 Node 类型的对象的链表类(List)。假设它们具有正确重载的布尔比较,它可以对这些节点执行各种操作。问题是,我想将此 List 类与一种称为 Term 的特殊节点(具有系数和指数或度数的代数项)一起使用。我如何告诉我的 List 类使用 Term 函数(Term 具有特殊版本的 Print() 函数和比较运算符),即使它使用节点指针处理术语?例如,我的 Print() 类似于:

Node* walker=head;
while(walker)
{
     walker->Print();
     walker=walker->next;
}

除了没有 Node::Print() 之外,我希望它调用 Term::Print()!我是否必须创建一个全新的 List 类来处理 Term 类对象?

4

3 回答 3

1

这是多态性的一个经典例子。您可以像 WhozCraig 建议的那样将函数 Print() 添加到您的 Node 类。(请阅读 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 :)

希望这可以帮助!

于 2012-11-16T21:34:10.863 回答
0

您已经偏离了通常的列表设计 - 建议使用模板而不是从Node类派生。然后,您需要一种foreach方法,该方法将在每个节点上执行操作,在这种情况下为print. 强烈建议使用 C++ 标准库容器,而不是编写所有这些“原始”代码。

另一种选择(不那么标准且存在设计缺陷)是派生出一个PrintList将调用该函数的Print函数,并且它需要被模板化或根据Term节点来完成,因为编译器会期望这个函数。

于 2012-11-16T20:52:12.180 回答
0

三个选择:-

在现实世界中,您将使用std::list或类似的容器类

或者,您可以将 Print() 作为虚拟方法添加到 Node,(并可能使其抽象)

class Node {
  ...
  virtual void Print() = 0;
}

或者,您可以使用将 Node* 转换为 Term*

    Term *t = boost::polymorphic_cast<Term*>(walker);
    t->Print();
于 2012-11-16T21:32:31.523 回答