OberonCore
https://forum.oberoncore.ru/

POINTER TO ANYREC
https://forum.oberoncore.ru/viewtopic.php?f=29&t=275
Страница 1 из 1

Автор:  Евгений Семашко [ Понедельник, 24 Июль, 2006 00:14 ]
Заголовок сообщения:  POINTER TO ANYREC

Доброго времени суток, господа.
У меня ест ьтакой вопрос: я создал процедуру добавления элемента в начало списка.
Код:
PROCEDURE AddToList (VAR head: ANYPTR; elem: ANYPTR);
BEGIN
   WITH head : PFodder DO
         WITH elem: PFodder DO
            elem.next := head;
            head := elem;      
         END;
      |   head: PMineralSubstance DO
         WITH elem: PMineralSubstance DO
            elem.next := head;
            head := elem;      
         END;
      END;      
END AddToList;


Так вот. В коде программы я пишу:
Код:
AddToList(head,p);


head и p в данном случае - PFodder.
Как мне думается, если Fodder является потомком ANYREC, то все должно быть хорошо. А на самом деле возникает ошибка несоответствия типов параметров - фактического и формального. Я подозреваю что это связано с тегами, но в данном случае не очень понятно, можно ли этого избежать?

Автор:  Сергей Губанов [ Понедельник, 24 Июль, 2006 09:45 ]
Заголовок сообщения:  Re: POINTER TO ANYREC

Если процедура объявлена так:
PROCEDURE AddToList (VAR head: ANYPTR; elem: ANYPTR);
то и передавать в качестве VAR параметра Вы должны именно ANYPTR.
Код:
VAR head, elem: PFodder;
  pointer: ANYPTR;
BEGIN
  ...
  pointer := head;
  AddToList(pointer, elem);
  head := pointer(PFodder);

Но тогда смысла в такой процедуре становится маловато.

Ну, попробуйте её оформить как функцию (без VAR параметров), как-нибудь так:

list := Attach(list, element)(PFodder);

А ещё лучше, не поленитесь и напишите типизированные варианты процедур.

Автор:  Евгений Семашко [ Понедельник, 24 Июль, 2006 11:50 ]
Заголовок сообщения:  Re: POINTER TO ANYREC

Сергей Губанов писал(а):
А ещё лучше, не поленитесь и напишите типизированные варианты процедур.


Как раз это я и написал, но это мне не нравится :(, поскольку надо писать для каждого типа свою процедуру. Хорошо, что здесь только две операции. А если бы их было 50, 10? Как бы мой код увеличился...
Да, видимо, сделаю функцию... Хотя хочется сделать процедуру. Ну джа ладно. Спасибо.

Автор:  Сергей Губанов [ Понедельник, 24 Июль, 2006 14:23 ]
Заголовок сообщения:  Re: POINTER TO ANYREC

Евгений Семашко писал(а):
Хорошо, что здесь только две операции. А если бы их было 50, 10? Как бы мой код увеличился...


Ой, да ладно... :D

---

Я односвязными списками обычно так пользуюсь:
Код:
TYPE
  List = POINTER TO RECORD
    head: Head;
    tail: List
  END;

  PROCEDURE NewList (head: Head; tail: List): List;
    VAR list: List;
  BEGIN NEW(list); list.head := head; list.tail := tail;
    RETURN list
  END NewList;

  ...
  list := NewList(head, list); (* добавить элемент в начало списка *)
  ...

где тип Head - для каждого типа списка свой.

Автор:  Илья Ермаков [ Вторник, 25 Июль, 2006 00:22 ]
Заголовок сообщения: 

Почему не использовать такой вариант
Код:
   TYPE
      ListItem = POINTER TO RECORD
         next: ListItem
      END;

   PROCEDURE AddToList (VAR head: ListItem; List: ListItem);
   BEGIN
      elem.next := head;
                head := elem;     
   END AddToList;

и не наследовать свои типы от ListItem?

Автор:  Илья Ермаков [ Вторник, 25 Июль, 2006 00:26 ]
Заголовок сообщения: 

А вообще "ради удобства" никакой нужды скрывать две операции с указателем за процедурой нет.
Если же речь идет об инкапсулсуляции, т.е. указатели скрыты, то тогда надо вводить тип-контейнер, который хранит список внутри себя и с ним работает.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/