无法为受保护类型编写聚合

时间:2015-03-21 20:58:18

标签: ada gnat

我有以下功能

function Allocate(V : Value_Type; N : access Node) return access Node is
begin
    return new Node'(Value => V, Next => N);
end Allocate;

在编译时,GNAT抱怨期望访问Node,但却找到了复合类型。这似乎破了。

节点是:

protected type Node is
    --Various routines
private
    Value : Value_Type;
    Next : access Node;
end Node;

我已恢复为非任务类型,并且没有确切的错误消息。这是我多次见过的,例如,只使用:

return (Value => V, Next => N);

或类似的。我在使用“new Type”()“时从未见过它。

2 个答案:

答案 0 :(得分:3)

正确,没有受保护类型的聚合。正如Simon在他的回答中所说,受保护的字段是私有的,只能在受保护类型的主体内可见(或者可能稍后在受保护类型的私有部分中)。外面的世界根本看不到田野。因此,您必须添加一个受保护的过程来设置字段:

protected type Node is
    --Various routines
    procedure Set_Value(V : Value_Type);
    procedure Set_Next(N : access Node);
private
    Value : Value_Type;
    Next : access Node;
end Node;

并调用Allocate中的程序:

function Allocate (V : Boolean; N : access Node) return access Node is
   New_Node : access Node;
begin
   New_Node := new Node;
   New_Node.Set_Value (V);
   New_Node.Set_Next (N); 
   return New_Node;
end Allocate;

(或者像Simon的回答一样使用扩展回报 - 我认为它会起作用。)

注意:我没有测试过这个。

如果ValueNext在受保护对象的整个生命周期中永远不会改变,另一种可能性是使用判别式:

protected type Node (Value : Value_Type; Next : access Node) is ...

现在你可以说

return new Node(Value => V, Next => N);

请注意,此语法中没有刻度线!我没有测试过这个,所以我不确定它会起作用。我认为在判别列表中引用相同类型是可以接受的,但我不确定。

答案 1 :(得分:2)

ValueNext唯一可见的地方(当然除了Node规范的私有部分之外)是在他们自己的Node中体。

我无法在Allocate内看到Node的写法。我放弃了

function Allocate (V : Boolean) return access Node is
begin
   return N : access Node do
      N := new Node;
      N.Next := Node'Access;
      N.Value := V;
   end return;
end Allocate;

一路上收到消息,包括

  

protected function cannot modify protected object
  protected type cannot be used as type mark within its own spec or body(所以你不能说Node'Access
  invisible selector "Value" for type “Node"

所以我认为你需要使用某种包装器。

相关问题