Цена использования генериков

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Сообщение vada »

Не получается. {$mode objfpc}
Опять получаем: Error: Operator is not overloaded: "TConturPoint" = "TConturPoint"
http://www.freepascal.org/docs-html/ref/refse88.html#x187-19700015.5 Не помогло
Сделал {$mode delphi}. Работает.
sts
энтузиаст
Сообщения: 519
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

если генерики нормально реализованы то нет никакого оверхеда, вообще нету (по сравнению с ручным унаследованием и перекрытия методов)
я смотрел исходники (8 мес назад) это грусно, это даже не генерики а тупые шаблоны (тогда были)
Аватара пользователя
pda
постоялец
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение pda »

alexs писал(а):А создать наследника от TList нельзя было?

Нет, потому что в ряде методов тип уже прибит гвоздями. Например, TList.Add(опа). Здесь в потомке вы уже свой тип не переопределите. Правда, в этом конкретном случае есть вариант обойтись без генериков. Можно использовать не TList, а TObjectList, определив структуру данных не как record, а как наследника TObject. Если с некоторым оверхедом готовы мириться, то способ работает.
Аватара пользователя
hinst
энтузиаст
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Сообщение hinst »

вам надо пакет fcl-stl посмотреть, лежит где-то с компилятором
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Сообщение vada »

Использование генериков создает еще проблему.
Нажимаю Ctrl+Space и получаю вместо ожидаемого продолжения метода класса
typesdemos.pas(20,23) Error: ожидается ;, найдено <

Код: Выделить всё

{$mode delphi}{$H+}
.......
type

 TBodyArray = TFPGList<TBodyBetweenCross>;
....

Причем, компилируется все влет. Только подтаскивай.

На борту:
Windows XP
Lazarus 0.9.30.4
FPC 2.6.0
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

vada писал(а):Использование генериков создает еще проблему.
Нажимаю Ctrl+Space и получаю вместо ожидаемого продолжения метода класса [...]

На борту:
Windows XP
Lazarus 0.9.30.4
FPC 2.6.0


Обновись на релиз 1.0.
Аватара пользователя
vada
энтузиаст
Сообщения: 691
Зарегистрирован: 14.02.2006 12:43:17

Сообщение vada »

Да. В 1.0 все в шоколаде! Спасибо!
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

В нашей CoreLib решил использовать компромиссный способ -- "зарезервированные" поля и приведение к потомкам. В модулях CoreClasses и CoreStrings поля обозначены комментариями { placeholder } и { hold }, а имена потомков для приведения оканчиваются на Cast (по сути это хак-классы).

Для мейнстримного программирования такой способ, понятное дело, небезопасен, но в рамках внутреннего проекта -- вполне. ИЧСХ, подходит он именно для контейнеров, с их вполне формализуемыми и "угадываемыми" полями.

Архитектура CoreLib закладывалась много лет назад, и главной задачей было сохранение совместимости c Delphi 6/7, отсюда и такой изврат. Впрочем, раз способ работает, почему бы и нет?
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

По мотивам своего поста написал статью, которая стала видна с открытием нового сайта.
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

Vapaamies писал(а):По мотивам своего поста написал статью, которая стала видна с открытием нового сайта.


Прочитав статью, написал код решающий половину проблем вот с этим:
Vapaamies писал(а):Соглашение по структуре потомков небезопасно, ибо совершенно не контролируется компилятором.


Добавлено спустя 4 часа 3 минуты 37 секунд:
stanilar писал(а):написал код


Прошу прощения за не совсем рабочий код, писал пока мысль не пропала (да, я помню - поспешишь людей насмешишь).
Спешу(опять) исправиться:

Код: Выделить всё

type

  TListItem = class;

  TListItemClass = class of TListItem;

  TListItem = class
  private
  //  { placeholder }  FOwner: TContainer;
  //  { placeholder }  FPrior, FNext: TListItem;
  public
    function Append(Item: TListItemClass): TListItem; virtual; abstract;
  end;

  TList = class
  private
  //  { placeholder }  FFirst, FLast: TListItem;
    FCount: Cardinal;
  public
    function Append(Item: TListItemClass) : TListItem; virtual; abstract;
  // properties
    property Count: Cardinal read FCount;
  end;

implementation

type
  TListCast = class;

  TListItemCast = class(TListItem)
    FOwner: TListCast;
    FPrior, FNext: TListItemCast;
  public
    function Append(Item: TListItemClass) : TListItem; override;
  end;

  TListCast = class(TList)
    FFirst, FLast: TListItemCast;
  public
    function Append(Item: TListItemClass) : TListItem; override;
  end;


function TListItemCast.Append(Item: TListItemClass) : TListItem;
var Tmp : TListItemCast;
begin
  if Item = nil then Exit;

  Result := TListItemClass.Create;
  Tmp := TListItemCast(Result);

  Tmp.FOwner := FOwner;
  Tmp.FPrior := Self;
  Tmp.FNext := FNext;

  FNext := Tmp;
  if FOwner <> nil then
    with FOwner do
    begin
      Inc(FCount);
      if FLast = Self then
        FLast := Tmp;
    end;
end;

function TListCast.Append(Item: TListItemClass) : TListItem;
begin
  if Self.FLast <> nil then // приведение
    Result := Self.FLast.Append(Item)
  else
    //Grab(Item);
end;
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

stanilar писал(а):Прошу прощения за не совсем рабочий код, писал пока мысль не пропала

Что-то идеи кода я не понял. Могу уточнить, что (теоретическая) небезопасность является необходимой платой за гибкость потомков, и обойти ее не удастся.

На самом деле всё не так страшно, и при нарушении соглашения в каком-либо из потомков соответствующая связка элемент-контейнер попросту не будет работать, выдавая AV. Это станет понятно сразу же, при сколь-нибудь серьезном использовании контейнеров. Правда, ошибка будет выявлена лишь на этапе отладки, а не компиляции, -- в этом и заключается небезопасность. И всё. Всё же Паскаль -- не Си, где переполнение буфера сплошь и рядом.

Понял также, что для полного понимания пока недостает примеров использования контейнеров. Примеры скоро будут: как только появится код приложений, использующих CoreLib. Скорее всего, таковым станет Pet. Возможно, будет еще одна статья по теме.
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

Vapaamies писал(а):Что-то идеи кода я не понял.


Используя классовые ссылки добавить в код полноценную проверку типов компилятором.
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

Vapaamies писал(а):Скорее всего, таковым станет Pet


Хотите использовать TApplication как контейнер?
Ответить