Есть библиотека для работы с динамическими структурами данных. Ее очень упрощенная часть представлена ниже (компилятор - FPC 2.0.0 под Win32):
{$mode ObjFpc}
Type
  T = Integer;
  ptitem = ^titem;
  titem = Object
    info: T;
    next, prev: ptitem;
    Constructor init(x: T; nxt, prv: ptitem);
    Destructor done;
  End;
Type
  TList = Object
  Private
    first, last: ptitem;
    Function isEmpty: Boolean;
  Public
    Constructor Create;
    Destructor Destroy; Virtual;
    Procedure append(x: T);
    Procedure insert(x: T);
    Procedure Print;
  End;
Operator + (Const L: TList; it: T) R: TList;
Begin
  L.append(it);
  result := L;
End;
Operator + (it: T; Const L: TList) R: TList;
Begin
  L.insert(it);
  result := L;
End;
Constructor titem.init(x: T; nxt, prv: ptitem);
Begin
  info := x;
  next := nxt; prev := prv;
End;
Destructor titem.done;
Begin End;
(* tlist *)
Constructor TList.Create;
Begin
  first := nil; last := nil;
End;
Destructor TList.Destroy;
Begin
  // ...
End;
Function TList.isEmpty: Boolean;
Begin
  isEmpty := (first = nil);
End;
{
  insert new item to the start of list
}
Procedure TList.insert(x: T);
Var p: ptitem;
Begin
  new(p, init(x, first, nil));
  If p <> nil Then Begin
    If isEmpty Then last := p
    Else first^.prev := p;
    first := p;
  End;
End;
{
  append new item to the end of list
}
Procedure TList.append(x: T);
Var p: ptitem;
Begin
  new(p, init(x, nil, last));
  If p <> nil Then Begin
    If isEmpty Then first := p
    Else last^.next := p;
    last := p;
  End;
End;
Procedure TList.Print;
Var pt: ptitem;
Begin
  Write('<');
  pt := first;
  While pt <> nil Do Begin
    write(pt^.info, ' ');
    pt := pt^.next
  End;
  WriteLn('>')
End;
var
  list_int: TList;
  i: integer;
begin
  list_int.create;
  // Здесь работаем по-старинке: 
  list_int.insert(10);      // Добавляем элемент в начало списка
  list_int.insert(20);      // ...
  list_int.append(30);    // Добавляем элемент в конец списка
  list_int.append(40);    // ...
  list_int.print;
  // А здесь - используем возможности современного компилятора - 
  // перегрузку операций
  for i := 1 to 8 do
    list_int := (15 * i) + list_int + (10 * i);
  list_int.print;
  list_int.destroy;
end.
 Все компилируется и работает. Меня интересует такой вопрос: насколько удобно будет пользователю библиотеки перейти от привычной формы записи (в виде процедур) к записи вида:
ListObj := 12 + 17 + ListObj + 24 + 32 + 78; { <--- Это, кстати, тоже работает... }
 , и стоит ли вообще предоставлять ему такую возможность и заморачиваться с перегрузкой операций?Еще кое-что... Тип T не всегда будет Integer, вполне возможно, что там будет указатель на какой-то объект. Вопрос, собственно, в том, распространяются ли на operator overloading правила наследования, то есть, смогу ли я передавать левым/правым операндом, например, указатели на объекты, находящиеся на разном уровне иерархии наследования, или только указатель на базовый класс?

 
 


 volvo   
