Наследование шаблонов

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

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

Наследование шаблонов

Сообщение hinst » 25.12.2009 18:16:57

Кто-нибудь знает, как отнаследовать шаблон?
Код: Выделить всё
type generic TG<G> = class
end;


Так не работает:
Код: Выделить всё
type generic TGG<G> = class(TG<g>)
end;


Так тоже не работает:
Код: Выделить всё
type generic TGG<G> = class(TG)
end;


оно вообще возможно?
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Наследование шаблонов

Сообщение alexrayne » 26.12.2009 13:32:04

сильно подозреваю что наследовать шаблон невозможно. ибо шаблон ето не код, а устанавливать связи наследования компилятор может только при наличии реальных классов через их VMT.
насколько я понимаю VMT генерится как раз при создании класса из шаблона.

наследование шаблонов должно предполагать что одновременно с классом потомка будут генерится и классы предков. и в етом ничего невозможного нет, но они тогда будут скрытыми так как вы незнаете их имена.
alexrayne
постоялец
 
Сообщения: 125
Зарегистрирован: 03.12.2008 16:56:26

Re: Наследование шаблонов

Сообщение alexs » 26.12.2009 20:31:10

А зачем?

P.S.
Я вобще смысла в шаблонах большого не вижу. А ещё их наследовать...
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Наследование шаблонов

Сообщение Astralis » 27.12.2009 01:30:19

На данный момент наследование возможно только от класса, в том числе и от специализации шаблона
Код: Выделить всё
type generic TGG<G> = class(specialize TG<TObject>)
end;


при этом такой код будет пока не работает
Код: Выделить всё
type generic TGG<G> = class(specialize TG<G>)
end;


и данный код тоже не работает
Код: Выделить всё
generic TContainer<TData> = class
function GetIterator: TIterator<TData>;
end;

generic TIterator<TData> = class
constructor Create(FParent: TContainer<TData>)
end;


а чтобы понять всю красоту идеи шаблонов, достаточно посмотреть следующие две строки (TODO):
Код: Выделить всё
   TGenericCollection<T: TCollectionItem> = class(TComponent)
   ...implement TCollection and use T
   end;

   TCollection = TGenericCollection<TCollectionItem>;


а на данный момент пока можно просто в каждом классе иметь поле типа TClass
Аватара пользователя
Astralis
новенький
 
Сообщения: 45
Зарегистрирован: 06.06.2007 20:33:05
Откуда: Tvercity-Annet

Re: Наследование шаблонов

Сообщение alexs » 27.12.2009 11:12:47

Astralis писал(а):а чтобы понять всю красоту идеи шаблонов, достаточно посмотреть следующие две строки

Я в принципе не понимаю - зачем нужна куча классов с почти одинаковой реализацией?
моет в консерватории проще что-то подправить?
На мой взгляд - это больше говорит об ошибках проектирования.
PS
я и множественное наследование за свою жизнь не разу не испытывал потребности использовать...
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Наследование шаблонов

Сообщение Дож » 01.01.2010 21:52:21

alexs
Замечательная логика без единого примера и следствий вида "я не понимаю зачем нужны => их использование говорит об ошибках проектирования" :)

Я в принципе не понимаю - зачем нужна куча классов с почти одинаковой реализацией?

Можно по аналогии размышлять зачем нужны функции.

Зачем во многих местах вызывать f, ведь везде будет сделано одно и то же?

Я вот ни разу в своей жизни функции не использовал.

На мой взгляд - их использование говорит об ошибках проектирования.

ПС
потребность в while, кстати, тоже не испытываю.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Наследование шаблонов

Сообщение Verx0Laz » 02.01.2010 01:36:22

Перевожу на плохой русский Лёхин вопрос "А зачем доставать ухо через голову?" ...Если конечно это в принципе нуждается в переводе. Итак, непосредственно перевод:
- На кой ляд вам понадобилось доводить до ума столь громоздкую и замысловатую кодовую конструкцию, когда все практически ценные задачи, которые способна решить данная конструкция, решаются более простыми и красивыми методами? Возможно, что-то, действительно важное в этом вопросе, ускользнуло от нашего внимания? Не затруднит-ли вас сформулировать нам это "что-то"?
Абсолютно без намёка на издевательство, подначку или что-то в этом роде... просто самому интересно
Аватара пользователя
Verx0Laz
постоялец
 
Сообщения: 125
Зарегистрирован: 11.09.2007 11:24:07

Re: Наследование шаблонов

Сообщение Vadim » 02.01.2010 06:53:12

Verx0Laz писал(а):просто самому интересно

Если ещё короче - зачем вообще нужны шаблоны? И какую выгоду они дают по сравнению с другими средствами? ;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Наследование шаблонов

Сообщение Дож » 02.01.2010 12:28:37

Шаблоны нужны для снижения копипаста.

Пример применения: реализация дин. массива со стандартными возможностями, с методами удаления заданного элемента. Допустим, что я пишу программу для работы с графикой, у меня есть куча структур вида TVec2f = packed record..., TVec3f = packed record..., TVec4f = packed record..., TMatrix4f = array[0..15] of Float, ...

Их нужно будет хранить в дин. массиве, и их мне придется отправлять непрерывным участком в файл, т.е. одним махом при помощи BlockWrite.

Ясно, что обычным array of ... получится копипаст - придется для каждого типа писать свою функцию удаления.

С дженериками никакого копипаста не будет
Код: Выделить всё
type
generic TArrayOf<TItem> = class(TObject)
  var private
    FItems: array of TItem;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(const Item: TItem);
    procedure Del(const Item: TItem); overload;
    procedure Del(Index: Integer); overload;
    function Find(const Item: TItem): Integer;
    property Ptr: Pointer; // выдает @FItems[0]
    property Items[Index: Integer]: TItem;
    property Count: Integer; // заменитель Length/SetLength
end;

TArrayOfVec2f = specialize TArrayOf<TVec2f>;
TArrayOfVec3f = specialize TArrayOf<TVec3f>;
TArrayOfVec4f = specialize TArrayOf<TVec4f>;
TArrayOfMatrix4f = specialize TArrayOf<TMatrix4f>;
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Наследование шаблонов

Сообщение alexs » 03.01.2010 00:52:11

Дож
Этот пример , что ты приводишь - он всегда и фигурирует. Только вопрос - зачем? Чем тебя обычная колекция не устраивает?
Или обычный динамический массив?
Я вижу от применения шаблонов только непомерное раздувание итогового кода исполняемого файла, ибо всё это в итоге сведётся к томуже копипасту - только скрытому.
Может лучше подумать на этапе постановки задачи и начального проектирования, чтобы исключить такие казусы?
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Наследование шаблонов

Сообщение Дож » 03.01.2010 01:41:02

Этот пример , что ты приводишь - он всегда и фигурирует. Только вопрос - зачем? Чем тебя обычная колекция не устраивает?
Или обычный динамический массив?

Я написал чем.

Я вижу от применения шаблонов только непомерное раздувание итогового кода исполняемого файла, ибо всё это в итоге сведётся к томуже копипасту - только скрытому.

Каша какая-то...

С одной стороны жалоба на раздувание кода - "непомерное раздувание итогового кода исполняемого файла".

С другой стороны утверждается, что будет так же - "сведётся к томуже копипасту - только скрытому".

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

Может лучше подумать на этапе постановки задачи и начального проектирования, чтобы исключить такие казусы?

Задача поставлена в предыдущем моем посте и пересмотру не подлежит - а перепроектировать можно сколько угодно, вперед. Дин. массивы и коллекции не устраивают - я написал чем.

Казус - это имеется ввиду раздувание кода? Любое решение имеет плюсы и минусы, наличие одного казуса "раздувание итогового кода исполняемого файла" не является веским основанием ставить крест на дженериках.

Может тебе лично не нужно и не выгодно использовать дженерики. Из этого нельзя делать выводов о том, что они не нужны никому в любой ситуации.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Наследование шаблонов

Сообщение alexs » 03.01.2010 03:01:07

ты меня не понял
Есть механизм - колекции. Они в принципе могут хрнаить что угодно. Почему не пользоваться ими?
Если тебе нужэен в них определённый функционал - просто сделай наследника.

Дож писал(а):С одной стороны жалоба на раздувание кода - "непомерное раздувание итогового кода исполняемого файла".

С другой стороны утверждается, что будет так же - "сведётся к томуже копипасту - только скрытому".

А разве это не одно и тоже?
Разве шаблоны в итоге не развораичваются в код?
При
Дож писал(а):TArrayOfVec2f = specialize TArrayOf<TVec2f>;
TArrayOfVec3f = specialize TArrayOf<TVec3f>;

У тебя будет в коде 2 одинаковых набора методов, только один - для работы с типом <TVec2f>, а второй - <TVec3f>
Это и есть раздувание кода и скрытый копипаст - только не ты его делаеш а компилятор. А результат тот-же - в готовом исполняемом файле куча дублированого кода, который отличается маленьким нюансом - типом обрабатываемых данных (и то, скоре всего не просто типом, а указателем на этот тип).
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Наследование шаблонов

Сообщение FedeX » 03.01.2010 08:47:08

alexs
По-моему Дож всё-таки прав - по-моему он хочет сказать (и говорит), что коллекциями именно в этом случае не обойтись, т.к. (см. условие), массив должен быть сплошной (не указателей на рекорды или обьекты, а "сплошной"). В этом случае в обычной ситуации нормальное решение - плодить несколько похожих объектов (со всеми последствиями "раздувания кода") или же отказаться вообще от паскалевских массивов и работать с указателем на память, где храниться массив и размерами элементов (что не всегда удобно). Тут же генерики позволяют (как уже было сказано), просто напросто сократить колличество кода, причём (я тоже так считаю) весьма изящьно.
пс. я repeat использую раз в десять тыщ. лет, но иногда эта конструкция хорошо сокращает (читай делает изящьнее) код.
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Наследование шаблонов

Сообщение Дож » 03.01.2010 12:29:40

FedeX все правильно говорит, не буду его повторять.

Есть механизм - колекции. Они в принципе могут хрнаить что угодно. Почему не пользоваться ими?

Напиши же наконец то же, что и я, но с коллекциями, я заинтригован :)

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

Как лично я представляю это решение.
Там придется для каждого из перечисленных мною типов писать своего наследника TCollectionItem -> TCollectionItemVec2f, TCollectionItemVec3f, TCollectionItemVec4f, TCollectionMatrix4f.
Потом для каждого типа писать своего наследника TCollection, чтобы был удобный массив Items с нужным типом: TVec2f, ..., TMatrix4f (изначально ведь Items выдает TCollectionItem, а мы же не хотим при каждом использовании вытворять TCollectionItemVec2f(Items[I]).Value).
Писать функцию Ptr, скидывающую все данные в сплошной массив. Для этого потребуется для каждого TCollectionItem хранить размер типа, который он хранит (SizeOf(TVec2f), SizeOf(TVec3f), ...). И отвлечемся даже от того, что тут еще будут проблемы с утечкой памяти.

И вот мы получили то, с чего ты начал: Я в принципе не понимаю - зачем нужна куча классов с почти одинаковой реализацией?

alexs писал(а):
Дож писал(а):С одной стороны жалоба на раздувание кода - "непомерное раздувание итогового кода исполняемого файла".

С другой стороны утверждается, что будет так же - "сведётся к томуже копипасту - только скрытому".

А разве это не одно и тоже?
Разве шаблоны в итоге не развораичваются в код?

Нет, не одно и то же, это два разных утверждения. Разберем предложение "Я вижу от применения шаблонов только непомерное раздувание итогового кода исполняемого файла, ибо всё это в итоге сведётся к томуже копипасту - только скрытому."

Утверждение (а) "Я вижу от применения шаблонов только непомерное раздувание итогового кода исполняемого файла" означает (б) "если я не буду применять шаблоны, а воспользуюсь обычными дин. массивами, то итоговый файл будет занимать меньший размер".

Утверждение (в) "всё это в итоге сведётся к томуже копипасту - только скрытому" означает (г) "если я не буду применять шаблоны, а воспользуюсь обычными дин. массивами, то итоговый файл будет иметь такой же размер".

Если ты считаешь, что я неправ, то скажи где именно: когда говорю (a)=(б), когда говорю (в)=(г) или когда говорю (б)<>(г)?

У тебя будет в коде 2 одинаковых набора методов, только один - для работы с типом <TVec2f>, а второй - <TVec3f>
Это и есть раздувание кода и скрытый копипаст - только не ты его делаеш а компилятор. А результат тот-же - в готовом исполняемом файле куча дублированого кода, который отличается маленьким нюансом - типом обрабатываемых данных

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

Если боишься копипаста во всех его проявлениях - приведи решение вообще без копипаста. Без единого.

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

(и то, скоре всего не просто типом, а указателем на этот тип).

Параметр дженерика ведет себя так же как и обычный тип, нигде лишних указателей не будет. Иначе в приведенном мною коде свойство Ptr не работало бы.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Наследование шаблонов

Сообщение Bonart » 03.01.2010 14:48:51

alexs
Как раз в случае коллекций польза от генериков наиболее очевидна, так как избавляет от необходимости для каждого конкретного наследника писать нисходящее приведение типов, что избавляет от лишнего кода - физически компилятор спокойно генерирует один код для всего семейства коллекций объектов, от ошибок типизации - за типами следит компилятор и от нарушения принципа Лисков.
В случае же коллекций значений генерики позволяют для каждого размера данных получить оптимизированный код при единственном экземпляре исходника (копипаст есть, но на нижнем уровне) или менее эффективную общую реализацию с контролем типов.
Без генериков копипаста в любом случае получается больше, причем более опасного (надо поддерживать "копии" исходного кода).
Bonart
новенький
 
Сообщения: 81
Зарегистрирован: 29.06.2007 11:47:40

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

Рейтинг@Mail.ru