Конференция "Прочее" » Когда же наконец в Delphi for Win32 появятся дженерики
 
  • XentaAbsenta (15.04.08 11:48) [0]
    Сейчас я разрабатываю сервис для IRC, и из-за нехватки шаблонов и множественного наследования была даже мысль полностью пересесть на c++. Надо мной уже друзья смеются, называя меня шаблонизатором. Какие только трюки не приходится выкидывать чтобы не заниматься этим. Из-за нехватки этих фич код неимоверно распухает, хотя вполне можно было бы сделать его меньше. На самом деле HP разработала очень правильную библиотеку (STD), жаль, и очень жаль, что для делфей нет ничего подобного....
    С нетерпением жду D2008.
  • tesseract © (15.04.08 11:55) [1]

    > и из-за нехватки шаблонов и множественного наследования
    > была даже мысль полностью пересесть на c++.


    TInterfacedObject  ?

    ЗЫ : Почему просто классовую структурку не пририсовать хорошую ? Множественное наследование - палка о двух концах и одном геморое.

    ЗЫ2 : А чего тут смешного, смеються те, кто две книжки проштудил и радуеться.
  • Palladin © (15.04.08 12:02) [2]

    > XentaAbsenta   (15.04.08 11:48)  

    разруха, она, знаете ли, в головах

    сколько лет разрабатываю и только считаные разы у меня мелькнула мысль, а вот здесь бы множественное наследование бы, было бы очень красиво... а шаблоны, в общем то прекрасно все разрабатывается и без них...
  • vuk © (15.04.08 12:03) [3]
    TInterfacedObject не лечит ни от отсутствия множественного наследования (если нужно именно наследование функциональности) ни от отсутствия дженериков.
  • Игорь Шевченко © (15.04.08 12:11) [4]
    ерундой страдаете уважаемый
  • oxffff © (15.04.08 12:33) [5]

    > vuk ©   (15.04.08 12:03) [3]


    А что насчет делегирования реализации интерфейсу или объекту?
    Механизм очень гибкий.
  • vuk © (15.04.08 12:43) [6]
    to oxffff ©   (15.04.08 12:33) [5]:
    >А что насчет делегирования реализации интерфейсу или объекту?
    А тут все просто. Делегирование - это не наследование. Причем, я согласен, множественное наследование - вещь, которая нужна крайне редко. Но заявлять о полной ненужность этой фичи, даже не имея под неё задач, не буду.
  • oxffff © (15.04.08 12:49) [7]

    > А тут все просто. Делегирование - это не наследование.


    Делегирование реализации полный аналог множественного наследования.
    Приведите пример обратного.

    Причем множественное наследование (которое вы привозносите :) ) имеет неприятный артифакт. А именно вызов виртуальной функции в конструкторе.
  • Alkid © (15.04.08 12:54) [8]

    > XentaAbsenta   (15.04.08 11:48)

    Не слушай их всех, я тебя поддерживаю.
    Шаблоны - хорошо, дженерики - почти так же хорошою, как шаблоны :)
    Без них можно, с ними - лучше. Опять же, парадокс Блаба.
  • vuk © (15.04.08 13:01) [9]
    to oxffff ©   (15.04.08 12:49) [7]:
    >Приведите пример обратного.
    Нет уж, если так хочится примеров, то это Вы приводите пример того, что это полный аналог. :)

    >которое вы привозносите :)
    Я? Это хде? :)
  • Игорь Шевченко © (15.04.08 13:03) [10]
    oxffff ©   (15.04.08 12:49) [7]


    > Делегирование реализации полный аналог множественного наследования.


    А мужики и не знали
  • Игорь Шевченко © (15.04.08 13:04) [11]
    oxffff ©   (15.04.08 12:49) [7]


    > (которое вы привозносите :) ) имеет неприятный артифакт


    превозносите.
    артефакт.

    пардон, spellchecker сработал
  • guav © (15.04.08 13:06) [12]
    > была даже мысль полностью пересесть на c++.

    ну так а почему нет, что за Delphi держит ?
  • Alkid © (15.04.08 13:17) [13]

    > Делегирование реализации полный аналог множественного наследования.

    Не совсем так.
    Делегирование реализации аналогично ЗАКРЫТОМУ наследованию, когда новый класс является наследником, но не подтипом родителя. В этом смысле, делегирование нескольким классам аналогичено множественному закрытому наследованию, т.е:


    class A : private B, private C
    {
    }
    ;


    с точки зрения интерфейса аналогично

    class A
    {
    private:
     B& b_delegate;
     C& c_delegate;
    }
    ;

  • vuk © (15.04.08 13:21) [14]
    to Alkid ©   (15.04.08 13:17) [13]:

    с точки зрения интерфейса аналогично

    class A
    {
    private:
    B& b_delegate;
    C& c_delegate;
    }
    ;



    А это вообще агрегирование в чистом виде.
  • Alkid © (15.04.08 13:27) [15]

    > А это вообще агрегирование в чистом виде.

    И что? Одно другом не мешает! :)
  • Slym © (15.04.08 13:33) [16]
    нафег эти дженерики? лучшеб inline функции (функция, но по месту применения инлайнится без call) сделали, так их нехватает...
  • Игорь Шевченко © (15.04.08 13:35) [17]

    > лучшеб inline функции (функция, но по месту применения инлайнится
    > без call) сделали,


    начиная с D2005 сделали.
  • guav © (15.04.08 13:39) [18]
    > [16] Slym ©   (15.04.08 13:33)

    Чем лучше ? Кроме времени выполнения инлайн ни на что инлайн не влияет. А темплейты кое-что таки дают.
  • Slym © (15.04.08 14:16) [19]
    Игорь Шевченко ©   (15.04.08 13:35) [17]
    начиная с D2005 сделали.

    мдя... низнал... я сижу на 7 :), надо потестить как инлайнит
    guav ©   (15.04.08 13:39) [18]
    время иногда критично, особенно заметно - если вызываемая функция мала по размеру, но в цикле вызывается много раз
  • oxffff © (15.04.08 14:32) [20]

    > Alkid ©   (15.04.08 13:17) [13]
    >

    >vuk ©   (15.04.08 13:21) [14]

    > > Делегирование реализации полный аналог множественного
    > наследования.
    >
    > Не совсем так.
    > Делегирование реализации аналогично ЗАКРЫТОМУ наследованию,
    >  когда новый класс является наследником, но не подтипом
    > родителя. В этом смысле, делегирование нескольким классам
    > аналогичено множественному закрытому наследованию, т.е:
    >
    >
    > class A : private B, private C
    > {
    > };
    >
    > с точки зрения интерфейса аналогично
    >
    > class A
    > {
    > private:
    >  B& b_delegate;
    >  C& c_delegate;
    > };


    Да ну? :)

    Вы про ключевое слово implements в Delphi слышали?
    Его можно помещать как в private, protected  и public разделы.
    И соответственно внешняя видимость для внешней среды может оставаться, может и закрываться  причем и для дочерних классов.
    Чего вам не нравится?

    Если цикл жизни делегируемому агрегату совпадает с циклом жизни делегирующего функционал, то это тоже самое наследование.
  • Kolan © (15.04.08 14:34) [21]
    > мдя… низнал… я сижу на 7 :),

    А ты думал, что если ты будешь долго сисдеть на D7, то туда добавят все что тебе надо? :)
  • Игорь Шевченко © (15.04.08 14:45) [22]

    > Вы про ключевое слово implements в Delphi слышали?


    И какое отношение это слово имеет к множественному наследованию ?
  • jack128_ (15.04.08 14:46) [23]

    > время иногда критично, особенно заметно - если вызываемая
    > функция мала по размеру, но в цикле вызывается много раз

    ну инклюдь её руками, что мешает.

    множественное наследование лично мне не нуно, а вот дженерики - было бы неплохо получить.  
    И моя личная мечта - анонимные функции и кортежи :-)
  • oxffff © (15.04.08 14:47) [24]

    > Alkid ©   (15.04.08 12:54) [8]
    >
    > > XentaAbsenta   (15.04.08 11:48)
    >
    > Не слушай их всех, я тебя поддерживаю.
    > Шаблоны - хорошо, дженерики - почти так же хорошою, как
    > шаблоны :)
    > Без них можно, с ними - лучше. Опять же, парадокс Блаба.
    >


    Только  generics поддерживает то, что принципиально нельзя в templates.
    А именно инстанцирование шаблона Run time.  :)
  • Kolan © (15.04.08 14:47) [25]
    > анонимные функции и кортежи :-)

    А чей-то такое?
  • Alkid © (15.04.08 14:48) [26]

    > Вы про ключевое слово implements в Delphi слышали?

    Не, не слышал. На дельфи программировать закончил 1.5 года назад, и то была почти всё вермя пятёрка. Что это ключевое слово делает?
  • oxffff © (15.04.08 14:50) [27]

    > Игорь Шевченко ©   (15.04.08 14:45) [22]
    >
    > > Вы про ключевое слово implements в Delphi слышали?
    >
    >
    > И какое отношение это слово имеет к множественному наследованию
    > ?


    Это имеет отношение к


    > Делегирование реализации аналогично ЗАКРЫТОМУ наследованию,
    >
    >   когда новый класс является наследником, но не подтипом
    >
    >  родителя.


    Фактически никто не мешает обойтись и без Implements.
    Только implements позволяет быстрее и эффективнее (функции обертки-делегирующие вызов не нужны).
  • Palladin © (15.04.08 14:51) [28]

    > Alkid ©   (15.04.08 14:48) [26]

    отделение мух от котлет при поддержке нескольких интерфейсов
  • Alkid © (15.04.08 14:53) [29]

    > отделение мух от котлет при поддержке нескольких интерфейсов

    Да, я уже прогуглил этот вопрос :)
    Занятная штука. Страуструп, кстати, подобное задумывал в С++, но в итоге отказался. В принципе это - синтаксический сахар, но это ХОРОШИЙ синтаксический сахар.
  • Игорь Шевченко © (15.04.08 14:57) [30]
    oxffff ©   (15.04.08 14:50) [27]

    Речь шла о том, что реализация интерфейсов - это не наследование.
  • Alkid © (15.04.08 15:01) [31]

    > Речь шла о том, что реализация интерфейсов - это не наследование.

    Формально - это не есть множественное наследование реализации. Но по сути даёт почти такие возможности, как и множественное наследование. А в чём-то даже по превосходит его. Так что я бы сказал, что с такой возможностью, идея множественного наследования реализации в НЕКОТРОЙ СТЕПЕНИ поддерживается в Дельфи.
  • oxffff © (15.04.08 15:09) [32]

    > Alkid ©   (15.04.08 14:48) [26]


    ACLASS=class
    procedure MethodOfClassA();
    end;

    BCLASS=class
    procedure MethodOfClassB();
    end;

    ContractA=interface
    ['{F0B051B7-755B-481D-817C-A78BE6AABDAB}']
    procedure MethodOfClassA();
    end;

    ContractB=interface
    ['{2D6EAFD0-3CA8-495D-98A9-95ED3F4A1906}']
    procedure MethodOfClassB();
    end;

    CClass=class(TinterfacedObject,ContractA,ContractB)
    InstanceA:ACLASS;
    InstanceB:BCLASS;
    protected
    property InstanceARef:ACLASS read InstanceA implements ContractA;
    property InstanceBRef:BCLASS read InstanceB implements ContractB;
    public
    constructor create;
    destructor destroy;override;
    end;
  • jack128_ (15.04.08 15:11) [33]
    кортежи - вот http://rsdn.ru/article/nemerle/NemerleIntro.xml#EUYAE

    анонимные функции. что то не не найду. Вобщем по сути - функции, описываемые по месту вызова. Соответсвенно - не имеющие имени. Очень удобно в качестве каллбеков использовать.
    например так:
    Tcallback = function (AObj: TMyObj; Data: Pointer): boolean;
    ...
    public
     function IterateChilds(Callback: TCallback): TMyObj;

    function IterateChilds(Callback: TCallback): TMyObj;
    begin
     for I := 0 to ChildCount then
       if Callback(Childs[I]) then
       begin
         Result := Childs[I];
         Exit;
       end;
     Result := nil
    end;

    Примеры

    function FindByID(AID: Integer): TMyObj;
    begin
     Result := IterateChild(<Result := AObj.ID = Integer(Data)>, Pointer(AID))
    end

    function FindByName(AName: string): TMyObj;
    begin
     Result := IterateChild(<Result := AObj.Name = string(Data)>, Pointer(AName))
    end

    function IterateToList(AList: TList);
    begin
     IterateChild(<TList(Data).Add(AObj);Result := False>, Pointer(AList))
    end

    или самый простой пример:  btnClose.OnClick := <Application.Terminate>;

    в угловых скобках - анонимные функции.

    PS вообще - почитай на rsdn статьи про немерле. там много интересного найдёшь.
  • Alkid © (15.04.08 15:12) [34]

    > oxffff ©   (15.04.08 15:09) [32]

    Занятственно :)
    Более многословно, чем множественное наследование в С++, но более гибко, ибо позволяет в рантайме менять "родителей".

    Интересно сравнить такую модель комбинации классов с тем, как это в С++ реализовано.
  • oxffff © (15.04.08 15:14) [35]

    > Alkid ©   (15.04.08 15:01) [31]


    Я бы сказал, что не уступает во всяком случае при грамотном использовании.

    Фактически  implements вставляет аналог делегирующей функции в виде в слот VMT интерфейса  в виде подстройки смещения и перехода на реализацию.
  • oxffff © (15.04.08 15:16) [36]

    > ибо позволяет в рантайме менять "родителей".


    Ну на с++ тоже самое написать можно, но ручками. :)
  • oxffff © (15.04.08 15:19) [37]

    > ибо позволяет в рантайме менять "родителей".


    да и не забываем что семантика класса в С++ это value type (стек), а в Delphi это ref type(куча, неуправляемая :) ).
  • Alkid © (15.04.08 15:25) [38]

    > oxffff ©   (15.04.08 15:14) [35]

    Ну, что он куда вставляет - это технические детали :) Меня интересуют другие вещи.
    Если рассматривать данный механизм, как инстумент построения архитектуры программы, то приходим к чему-то похожему на Smalltalk с его отдельным наследованием интерфейсов, т.е. основное дерево (граф?) наследования строится именно на интерфейсах (контрактах), а стоящие за ними реализации не обязаны образовывать некую стройную схему, возможно оставаясь фрагментарыми.

    Вопрос для обсуждения - эта схема позволяет реализовывать миксины? Т.е. когда я пишу класс, реализующий *часть* интерфейса и скидываю на него реализацию этой части, беря реализацию оставшейся части из другого класса или определяя у себя? Очевидно, что такое можно реализовать, руками расписывая заглушки вида:

    procedure TMyClass.MyMethod()
    begin
     delegate.MyMethod();
    end;


    Но это неудобственно. В принципе, виртуальное наследование в С++ решает подобную проблему. А тут как получается?
  • Alkid © (15.04.08 15:26) [39]

    > > ибо позволяет в рантайме менять "родителей".
    > Ну на с++ тоже самое написать можно, но ручками. :)

    Да. Не хватает настоящего метапрограммирования в С++. И много где :)


    > да и не забываем что семантика класса в С++ это value type
    > (стек), а в Delphi это ref type(куча, неуправляемая :) ).

    Гы. А указатели и ссылки для кого придуманы? :) И целый зоопарк смартпоинтеров туда же.
  • oxffff © (15.04.08 15:29) [40]

    >  А тут как получается?


    Здесь очень хорошо это получается. А именно.

    ACLASS=class
    procedure MethodOfClassA();
    end;

    BCLASS=class
    procedure MethodOfClassB();
    procedure MethodOfClassC();
    end;

    ContractA=interface
    ['{F0B051B7-755B-481D-817C-A78BE6AABDAB}']
    procedure MethodOfClassA();
    end;

    ContractB=interface
    ['{2D6EAFD0-3CA8-495D-98A9-95ED3F4A1906}']
    procedure MethodOfClassC();
    procedure MethodOfClassB();
    end;

    CClass=class(TinterfacedObject,ContractA,ContractB)
    InstanceA:ACLASS;
    InstanceB:BCLASS;
    protected
    procedure MethodOfClassCLocal();
    procedure ContractB.MethodOfClassC=MethodOfClassCLocal;


    property InstanceARef:ACLASS read InstanceA implements ContractA;
    property InstanceBRef:BCLASS read InstanceB implements ContractB;
    public
    constructor create;
    destructor destroy;override;
    end;
  • oxffff © (15.04.08 15:32) [41]

    > Гы. А указатели и ссылки для кого придуманы? :) И целый
    > зоопарк смартпоинтеров туда же.


    А что их тоже можно наследовать?

    Я поэтому и написал, что это ручками.
  • Alkid © (15.04.08 15:32) [42]
    Т.е. это:

    > procedure ContractB.MethodOfClassC=MethodOfClassCLocal;


    Перекрывает это:

    > property InstanceBRef:BCLASS read InstanceB implements ContractB;


    да?

    Симпатичненько получается.
  • vuk © (15.04.08 15:33) [43]
    oxffff ©   (15.04.08 14:32) [20]:
    >Вы про ключевое слово implements в Delphi слышали?
    Не только слышал но и использовал. И знаю, как оно работает. :)

    to Alkid ©   (15.04.08 15:25) [38]:
    >В принципе, виртуальное наследование в С++
    >решает подобную проблему. А тут как получается?
    Нет.
  • oxffff © (15.04.08 15:36) [44]

    > Не только слышал но и использовал. И знаю, как оно работает.
    >  :)


    Так привидите пример, что нельзя сделать в Delphi нельзя множественное наследование(подмешивание реализации с жизненным циклом совпадающим с агрегатом).

    А я вам покажу как это сделать. :)
  • Alkid © (15.04.08 15:36) [45]

    > Нет.

    Что нет?
    "Нет", в смысле, что тут никак не получается
    или "Нет", в смысле, что виртуальное наследование в с++ не позвонляет использовать миксины?
  • jack128_ (15.04.08 15:37) [46]

    > procedure MethodOfClassCLocal();procedure ContractB.MethodOfClassC=MethodOfClassCLocal;


    кста, в старших дельфях(в 2007 по крайней мере) - есть глюки, связанные с такой конструкцией.  Дельфя - никак не хотела понимать, что СontractB.MethodOfClassC реализуется методом MethodOfClassCLocal, а не тем классом, который в implements сидит.
  • oxffff © (15.04.08 15:42) [47]

    > Alkid ©   (15.04.08 15:32) [42]


    Более того можно менять семантику копирования агрегируемого RefCount, External RefCount, NoRefCount на лету.  Все больше ничего не скажу (это мой секрет).  :)
  • Alkid © (15.04.08 15:44) [48]

    > Более того можно менять семантику копирования агрегируемого
    > RefCount, External RefCount, NoRefCount на лету.  Все больше
    > ничего не скажу (это мой секрет).  :)

    Вах-вах!
    Но вообще, скажем прямо, эта возможность выглядит в дельфи несколько инородно, учитывая что базовая библиотека классов опирается на традиционную гомогенную иерархию классов. Возникает ощущение, что либо "направление развития" языка сильно (кардинально) меняется, либо фитчи начинают добавлять вообще без всякой системы.
  • oxffff © (15.04.08 15:51) [49]

    > Но вообще, скажем прямо, эта возможность выглядит в дельфи
    > несколько инородно, учитывая что базовая библиотека классов
    > опирается на традиционную гомогенную иерархию классов.


    Наследование есть и остается одиночным. Но существуют способы расширить реализацию по другому.

    >Вах-вах!

    Полный Вах-вах был когда я этот свой код отлаживал в отладчике. :)
    Потом нашел поменял две строчки местами и все заработало.
  • Kolan © (15.04.08 15:53) [50]
    > анонимные функции.

    Понял, кажется такое есть в Ruby
  • Kolan © (15.04.08 15:54) [51]
    Кортежи (tuples)
    Тоже понял.  Вполне логичное название в рел. субд тоже используются.

    ХЗ как все это может пригодится…
  • Alkid © (15.04.08 15:55) [52]

    > Наследование есть и остается одиночным. Но существуют способы
    > расширить реализацию по другому.

    Дело в том, что этот механизм несколько "конкурирует" с наследованием. :)
    Если брать выше, то он представляет собой серьёзную архитектурную альтернативу гомогенным иерархиям, которые традиционны для Дельфи.
    ИМХО, дельфи теряет в стройности от этого.
  • oxffff © (15.04.08 16:00) [53]

    > ИМХО, дельфи теряет в стройности от этого.


    Время покажет. Судить не нам.
 
Конференция "Прочее" » Когда же наконец в Delphi for Win32 появятся дженерики
Есть новые Нет новых   [134435   +33][b:0.001][p:0.002]