2016-03-09 5 views
0

Я изучаю дженерики в Ada, поэтому я внедрил простой связанный список. Вот мой код:Проблема с общим связанным списком

Linked_List.adb : 
    package body Linked_List is 
    function Get_First_Element return Element_Type is 
    begin 
     return Beginning.Value; 
    end Get_First_Element; 

    function Get_Last_Element return Element_Type is 
     temp : Node := Beginning.all; 
    begin 
     while temp.Next /= null loop 
     temp := temp.Next.all; 
     end loop; 
     return temp.Value; 
    end Get_Last_Element; 

    procedure Add_Element(data : Element_Type) is 
     newNode : access Node; 
    begin 
     newNode := new Node; 
     newNode.all.Value := data; 
     if Beginning.all.Next = null then 
     Beginning := newNode; 
     else 
     Last.Next := newNode; 
     Last := newNode; 
     end if; 

    end Add_Element; 

    procedure Remove_Element(data : Element_Type) is 
     temp : access Node := Beginning; 
     prev : Node; 
    begin 
     while temp /= null or temp.all.Value /= data loop 
     prev := temp.all; 
     temp := temp.Next; 
     end loop; 
     if temp = null then 
     return; 
     else 
     prev.Next := temp.all.Next; 
     end if; 
    end Remove_Element; 

    function Exists(data : Element_Type) return Boolean is 
     temp : access Node := Beginning; 
    begin 
     while temp /= null or temp.all.Value /= data loop 
     temp := temp.Next; 
     end loop; 
     if temp = null then 
     return false; 
     end if; 
     return true; 
    end Exists; 
begin 
    Beginning.all.Next := Last; 
end Linked_List; 

Linked_List.ads:

generic 
    type Element_Type is private; 
package Linked_List is 
    function Get_First_Element return Element_Type; 
    function Get_Last_Element return Element_Type; 
    procedure Add_Element(data : Element_Type); 
    procedure Remove_Element(data : Element_Type); 
    function Exists(data : Element_Type) return Boolean; 
private 
    type Node is 
     record 
      Value : Element_Type; 
      Next : access Node; 
     end record; 
    Beginning : access Node; 
    Last : access Node; 
end Linked_List; 

ли два файла компиляции хорошо. Вот моя основная процедура:

With Ada.Text_IO; use Ada.Text_IO; 
with Linked_List; 
procedure Main is 
    package List is new Linked_List(Element_Type => Integer); 
    lst : List; 
begin 

    for i in -5..5 loop 
     lst.Add_Element(i); 
    end loop; 
    lst.Remove_Element(1); 
    Put_Line(lst.Exists(2)); 
end Main; 

Здесь я столкнулся с проблемой. Вот ошибки, которые компилятор дает мне:

main.adb:5:10: subtype mark required in this context 
main.adb:5:10: found "List" declared at line 4 
main.adb:5:14: incorrect constraint for this kind of type 
main.adb:9:07: invalid prefix in selected component "lst" 
main.adb:11:04: invalid prefix in selected component "lst" 
main.adb:12:13: invalid prefix in selected component "lst" 

Я не могу понять эту ошибку:

main.adb:5:10: subtype mark required in this context 

Я могу понять, что другие ошибки говорят мне.

Редактировать: я исправил часть кода, и у меня появились новые сообщения об ошибках, все обновлено.

ответ

1

Пакеты по существу пространства имен, а не классы. Таким образом, вы не можете создать объект (экземпляр) этого пакета, который не экспортирует какие-либо типы.

Так что вы заявили что-то вроде одноэлементного: в вашем случае может быть только одно из них (для общего экземпляра), в вашем случае называется List. И список экспортирует подпрограммы, которые вы можете использовать.

Так что удалите декларацию lst : List; и вызовите подпрограммы напрямую, List.Add_Element(i); и ваш пример должен работать.

Если вам нужно больше связанных списков, вы можете создать экземпляр родового столько раз, сколько захотите. Список, который вы используете в каждом вызове, определяется именем созданного пакета.

Если вы хотите создать объекты типа, объявленные в пакете, вам придется объявить тип в пакете; добавление строки type Node is private; в публичную часть - это все, что вам нужно сделать; хотя type Node_Acc is access node; часто также полезен - тогда обновите свои объявления Beginning,Last, чтобы быть в этом типе.

Затем каждая подпрограмма должна знать, на каком узле они работают; поэтому им нужен узел в качестве аргумента, например function Get_First_Element(this : Node) return Element_Type;

Теперь вы можете объявить объекты типа Node и передать их в качестве аргументов. Если запись является помеченной записью, вы можете использовать либо function(argument), либо object.method нотацию, в зависимости от того, что делает программу более понятной.

-- package 
type Node is tagged private; 
private 
type Node is tagged record ...; 

-- client code 
    Head : List.Node; 
    ... 
    Add_Element(Head,1); 
    Head.Add_Element(2); 

 Смежные вопросы

  • Нет связанных вопросов^_^