0

我的任务需要创建一个包来创建异构(使用继承)双向链表。将节点插入列表很简单,但是当我必须找到包含某些信息的节点时,我的问题就出现了。

PACKAGE AbstList IS
   TYPE AbstractList IS LIMITED PRIVATE;

   TYPE Node IS TAGGED PRIVATE;
   TYPE NodePtr IS ACCESS ALL Node'Class;

   PROCEDURE Init_Head(List: ACCESS AbstractList);

   PROCEDURE InsertFront(List: ACCESS AbstractList; Item: IN NodePtr; Success: OUT Boolean);

   PROCEDURE InsertRear(List: ACCESS AbstractList; Item: IN NodePtr; Success: OUT Boolean);

   FUNCTION ListSize(List: ACCESS AbstractList) RETURN Integer;

   -- The following are commented out as they are not complete in the package body

   --FUNCTION FindItem(List: ACCESS AbstractList; Value: NodePtr) RETURN NodePtr;

   --PROCEDURE Delete(List: ACCESS AbstractList; Item: NodePtr);   

   --PROCEDURE Print(List: ACCESS AbstractList);


   PRIVATE
   TYPE Node IS TAGGED RECORD
      Rlink, Llink: NodePtr;
   END RECORD;

   TYPE AbstractList IS LIMITED RECORD
      Count: Integer := 0;
      Head: NodePtr := NEW Node;
   END RECORD;

END AbstList;

我用来插入列表的一条记录如下:

   TYPE CarName IS (GMC, Chevy, Ford, RAM);

   TYPE Car IS NEW AbstList.Node WITH RECORD 
      NumDoors: Integer;
      Manufacturer: CarName := GMC;   -- Default manu.
   END RECORD;

例如,我如何在列表中找到包含指定“制造商”的节点?有人建议我重载“=”运算符,尽管鉴于我所拥有的,我不确定这将如何工作。任何建议,将不胜感激。

4

2 回答 2

2

根据ARM,相等运算符是为非限制类型预定义的,您的 Node 类型就是这种情况。

如果您想要与默认行为不同的行为(记录中所有成员的平等,只需覆盖它。函数规范在同一页面中,只需T与您的Node类型(在本例中为Car)并写下您想要的

于 2018-03-28T07:29:49.407 回答
1

Ada 95 基本原理第 2 部分第 4 章在4.3 类宽类型和操作中说

预定义的相等运算符和成员资格测试被推广到适用于类范围的类型。与对此类类型的其他预定义操作一样,实现将取决于操作数的特定特定类型。但是,与正常的调度操作不同,如果操作数的标签不匹配,则不会引发 Constraint_Error。

对于相等,标签不匹配被视为不相等。仅当标签匹配时,才会对特定类型的相等性检查操作执行分派。这种方法允许程序安全地比较类范围标记类型的两个值是否相等,而无需首先检查它们的标记是否匹配。如 [RM83 4.5.2(12)] 中所述,在这种相等性检查中没有引发异常的事实与其他预定义的关系运算符一致。

所以你会期望能够说例如FindItem

   Current : Nodeptr := List.Head.Rlink;
begin
   ...
   if Value.all = Current.all then
      --  we’ve found a match

但预定义的相等性也Car包括Nodecomponents 。LlinkRlink

需要的是一个仅比较Car组件的相等操作。

您可以通过说来覆盖预定义的相等性

type Node is abstract tagged private;
function "=" (L, R : Node) return Boolean is abstract;

接着

type Car is new Abstlist.Node with record
   Numdoors: Integer;
   Manufacturer: Carname := Gmc;
end record;
overriding
function "=" (L, R : Car) return Boolean is
  (L.Manufacturer = R.Manufacturer and then L.Numdoors = R.Numdoors);

(这是 Ada 2012 语法)。

于 2018-03-30T13:57:37.223 回答