-
Сейчас я разрабатываю сервис для IRC, и из-за нехватки шаблонов и множественного наследования была даже мысль полностью пересесть на c++. Надо мной уже друзья смеются, называя меня шаблонизатором. Какие только трюки не приходится выкидывать чтобы не заниматься этим. Из-за нехватки этих фич код неимоверно распухает, хотя вполне можно было бы сделать его меньше. На самом деле HP разработала очень правильную библиотеку (STD), жаль, и очень жаль, что для делфей нет ничего подобного....
С нетерпением жду D2008.
-
> и из-за нехватки шаблонов и множественного наследования
> была даже мысль полностью пересесть на c++.
TInterfacedObject ?
ЗЫ : Почему просто классовую структурку не пририсовать хорошую ? Множественное наследование - палка о двух концах и одном геморое.
ЗЫ2 : А чего тут смешного, смеються те, кто две книжки проштудил и радуеться.
-
> XentaAbsenta (15.04.08 11:48)
разруха, она, знаете ли, в головах
сколько лет разрабатываю и только считаные разы у меня мелькнула мысль, а вот здесь бы множественное наследование бы, было бы очень красиво... а шаблоны, в общем то прекрасно все разрабатывается и без них...
-
TInterfacedObject не лечит ни от отсутствия множественного наследования (если нужно именно наследование функциональности) ни от отсутствия дженериков.
-
ерундой страдаете уважаемый
-
> vuk © (15.04.08 12:03) [3]
А что насчет делегирования реализации интерфейсу или объекту?
Механизм очень гибкий.
-
to oxffff © (15.04.08 12:33) [5]:
>А что насчет делегирования реализации интерфейсу или объекту?
А тут все просто. Делегирование - это не наследование. Причем, я согласен, множественное наследование - вещь, которая нужна крайне редко. Но заявлять о полной ненужность этой фичи, даже не имея под неё задач, не буду.
-
> А тут все просто. Делегирование - это не наследование.
Делегирование реализации полный аналог множественного наследования.
Приведите пример обратного.
Причем множественное наследование (которое вы привозносите :) ) имеет неприятный артифакт. А именно вызов виртуальной функции в конструкторе.
-
> XentaAbsenta (15.04.08 11:48)
Не слушай их всех, я тебя поддерживаю.
Шаблоны - хорошо, дженерики - почти так же хорошою, как шаблоны :)
Без них можно, с ними - лучше. Опять же, парадокс Блаба.
-
to oxffff © (15.04.08 12:49) [7]:
>Приведите пример обратного.
Нет уж, если так хочится примеров, то это Вы приводите пример того, что это полный аналог. :)
>которое вы привозносите :)
Я? Это хде? :)
-
oxffff © (15.04.08 12:49) [7]
> Делегирование реализации полный аналог множественного наследования.
А мужики и не знали
-
oxffff © (15.04.08 12:49) [7]
> (которое вы привозносите :) ) имеет неприятный артифакт
превозносите.
артефакт.
пардон, spellchecker сработал
-
> была даже мысль полностью пересесть на c++.
ну так а почему нет, что за Delphi держит ?
-
> Делегирование реализации полный аналог множественного наследования.
Не совсем так.
Делегирование реализации аналогично ЗАКРЫТОМУ наследованию, когда новый класс является наследником, но не подтипом родителя. В этом смысле, делегирование нескольким классам аналогичено множественному закрытому наследованию, т.е:
class A : private B, private C
;
с точки зрения интерфейса аналогично
class A
;
-
to Alkid © (15.04.08 13:17)
[13]:
с точки зрения интерфейса аналогично
class A
;
А это вообще агрегирование в чистом виде.
-
> А это вообще агрегирование в чистом виде.
И что? Одно другом не мешает! :)
-
нафег эти дженерики? лучшеб inline функции (функция, но по месту применения инлайнится без call) сделали, так их нехватает...
-
> лучшеб inline функции (функция, но по месту применения инлайнится
> без call) сделали,
начиная с D2005 сделали.
-
> [16] Slym © (15.04.08 13:33)
Чем лучше ? Кроме времени выполнения инлайн ни на что инлайн не влияет. А темплейты кое-что таки дают.
-
Игорь Шевченко © (15.04.08 13:35) [17]
начиная с D2005 сделали.
мдя... низнал... я сижу на 7 :), надо потестить как инлайнит
guav © (15.04.08 13:39) [18]
время иногда критично, особенно заметно - если вызываемая функция мала по размеру, но в цикле вызывается много раз
-
> 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 разделы.
И соответственно внешняя видимость для внешней среды может оставаться, может и закрываться причем и для дочерних классов.
Чего вам не нравится?
Если цикл жизни делегируемому агрегату совпадает с циклом жизни делегирующего функционал, то это тоже самое наследование.
-
> мдя
низнал
я сижу на 7 :),
А ты думал, что если ты будешь долго сисдеть на D7, то туда добавят все что тебе надо? :)
-
> Вы про ключевое слово implements в Delphi слышали?
И какое отношение это слово имеет к множественному наследованию ?
-
> время иногда критично, особенно заметно - если вызываемая
> функция мала по размеру, но в цикле вызывается много раз
ну инклюдь её руками, что мешает.
множественное наследование лично мне не нуно, а вот дженерики - было бы неплохо получить.
И моя личная мечта - анонимные функции и кортежи :-)
-
> Alkid © (15.04.08 12:54) [8]
>
> > XentaAbsenta (15.04.08 11:48)
>
> Не слушай их всех, я тебя поддерживаю.
> Шаблоны - хорошо, дженерики - почти так же хорошою, как
> шаблоны :)
> Без них можно, с ними - лучше. Опять же, парадокс Блаба.
>
Только generics поддерживает то, что принципиально нельзя в templates.
А именно инстанцирование шаблона Run time. :)
-
> анонимные функции и кортежи :-)
А чей-то такое?
-
> Вы про ключевое слово implements в Delphi слышали?
Не, не слышал. На дельфи программировать закончил 1.5 года назад, и то была почти всё вермя пятёрка. Что это ключевое слово делает?
-
> Игорь Шевченко © (15.04.08 14:45) [22]
>
> > Вы про ключевое слово implements в Delphi слышали?
>
>
> И какое отношение это слово имеет к множественному наследованию
> ?
Это имеет отношение к
> Делегирование реализации аналогично ЗАКРЫТОМУ наследованию,
>
> когда новый класс является наследником, но не подтипом
>
> родителя.
Фактически никто не мешает обойтись и без Implements.
Только implements позволяет быстрее и эффективнее (функции обертки-делегирующие вызов не нужны).
-
> Alkid © (15.04.08 14:48) [26]
отделение мух от котлет при поддержке нескольких интерфейсов
-
> отделение мух от котлет при поддержке нескольких интерфейсов
Да, я уже прогуглил этот вопрос :)
Занятная штука. Страуструп, кстати, подобное задумывал в С++, но в итоге отказался. В принципе это - синтаксический сахар, но это ХОРОШИЙ синтаксический сахар.
-
oxffff © (15.04.08 14:50) [27]
Речь шла о том, что реализация интерфейсов - это не наследование.
-
> Речь шла о том, что реализация интерфейсов - это не наследование.
Формально - это не есть множественное наследование реализации. Но по сути даёт почти такие возможности, как и множественное наследование. А в чём-то даже по превосходит его. Так что я бы сказал, что с такой возможностью, идея множественного наследования реализации в НЕКОТРОЙ СТЕПЕНИ поддерживается в Дельфи.
-
> 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;
-
кортежи - вот
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 статьи про немерле. там много интересного найдёшь.
-
> oxffff © (15.04.08 15:09) [32]
Занятственно :)
Более многословно, чем множественное наследование в С++, но более гибко, ибо позволяет в рантайме менять "родителей".
Интересно сравнить такую модель комбинации классов с тем, как это в С++ реализовано.
-
> Alkid © (15.04.08 15:01) [31]
Я бы сказал, что не уступает во всяком случае при грамотном использовании.
Фактически implements вставляет аналог делегирующей функции в виде в слот VMT интерфейса в виде подстройки смещения и перехода на реализацию.
-
> ибо позволяет в рантайме менять "родителей".
Ну на с++ тоже самое написать можно, но ручками. :)
-
> ибо позволяет в рантайме менять "родителей".
да и не забываем что семантика класса в С++ это value type (стек), а в Delphi это ref type(куча, неуправляемая :) ).
-
> oxffff © (15.04.08 15:14) [35]
Ну, что он куда вставляет - это технические детали :) Меня интересуют другие вещи.
Если рассматривать данный механизм, как инстумент построения архитектуры программы, то приходим к чему-то похожему на Smalltalk с его отдельным наследованием интерфейсов, т.е. основное дерево (граф?) наследования строится именно на интерфейсах (контрактах), а стоящие за ними реализации не обязаны образовывать некую стройную схему, возможно оставаясь фрагментарыми.
Вопрос для обсуждения - эта схема позволяет реализовывать миксины? Т.е. когда я пишу класс, реализующий *часть* интерфейса и скидываю на него реализацию этой части, беря реализацию оставшейся части из другого класса или определяя у себя? Очевидно, что такое можно реализовать, руками расписывая заглушки вида:
procedure TMyClass.MyMethod()
begin
delegate.MyMethod();
end;
Но это неудобственно. В принципе, виртуальное наследование в С++ решает подобную проблему. А тут как получается?
-
> > ибо позволяет в рантайме менять "родителей".
> Ну на с++ тоже самое написать можно, но ручками. :)
Да. Не хватает настоящего метапрограммирования в С++. И много где :)
> да и не забываем что семантика класса в С++ это value type
> (стек), а в Delphi это ref type(куча, неуправляемая :) ).
Гы. А указатели и ссылки для кого придуманы? :) И целый зоопарк смартпоинтеров туда же.
-
> А тут как получается?
Здесь очень хорошо это получается. А именно.
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;
-
> Гы. А указатели и ссылки для кого придуманы? :) И целый
> зоопарк смартпоинтеров туда же.
А что их тоже можно наследовать?
Я поэтому и написал, что это ручками.
-
Т.е. это:
> procedure ContractB.MethodOfClassC=MethodOfClassCLocal;
Перекрывает это:
> property InstanceBRef:BCLASS read InstanceB implements ContractB;
да?
Симпатичненько получается.
-
oxffff © (15.04.08 14:32) [20]:
>Вы про ключевое слово implements в Delphi слышали?
Не только слышал но и использовал. И знаю, как оно работает. :)
to Alkid © (15.04.08 15:25) [38]:
>В принципе, виртуальное наследование в С++
>решает подобную проблему. А тут как получается?
Нет.
-
> Не только слышал но и использовал. И знаю, как оно работает.
> :)
Так привидите пример, что нельзя сделать в Delphi нельзя множественное наследование(подмешивание реализации с жизненным циклом совпадающим с агрегатом).
А я вам покажу как это сделать. :)
-
> Нет.
Что нет?
"Нет", в смысле, что тут никак не получается
или "Нет", в смысле, что виртуальное наследование в с++ не позвонляет использовать миксины?
-
> procedure MethodOfClassCLocal();procedure ContractB.MethodOfClassC=MethodOfClassCLocal;
кста, в старших дельфях(в 2007 по крайней мере) - есть глюки, связанные с такой конструкцией. Дельфя - никак не хотела понимать, что СontractB.MethodOfClassC реализуется методом MethodOfClassCLocal, а не тем классом, который в implements сидит.
-
> Alkid © (15.04.08 15:32) [42]
Более того можно менять семантику копирования агрегируемого RefCount, External RefCount, NoRefCount на лету. Все больше ничего не скажу (это мой секрет). :)
-
> Более того можно менять семантику копирования агрегируемого
> RefCount, External RefCount, NoRefCount на лету. Все больше
> ничего не скажу (это мой секрет). :)
Вах-вах!
Но вообще, скажем прямо, эта возможность выглядит в дельфи несколько инородно, учитывая что базовая библиотека классов опирается на традиционную гомогенную иерархию классов. Возникает ощущение, что либо "направление развития" языка сильно (кардинально) меняется, либо фитчи начинают добавлять вообще без всякой системы.
-
> Но вообще, скажем прямо, эта возможность выглядит в дельфи
> несколько инородно, учитывая что базовая библиотека классов
> опирается на традиционную гомогенную иерархию классов.
Наследование есть и остается одиночным. Но существуют способы расширить реализацию по другому.
>Вах-вах!
Полный Вах-вах был когда я этот свой код отлаживал в отладчике. :)
Потом нашел поменял две строчки местами и все заработало.
-
> анонимные функции.
Понял, кажется такое есть в Ruby
-
Кортежи (tuples)
Тоже понял. Вполне логичное название в рел. субд тоже используются.
ХЗ как все это может пригодится
-
> Наследование есть и остается одиночным. Но существуют способы
> расширить реализацию по другому.
Дело в том, что этот механизм несколько "конкурирует" с наследованием. :)
Если брать выше, то он представляет собой серьёзную архитектурную альтернативу гомогенным иерархиям, которые традиционны для Дельфи.
ИМХО, дельфи теряет в стройности от этого.
-
> ИМХО, дельфи теряет в стройности от этого.
Время покажет. Судить не нам.