Форум: "Прочее";
Текущий архив: 2008.06.01;
Скачать: [xml.tar.bz2];
ВнизКогда же наконец в Delphi for Win32 появятся дженерики Найти похожие ветки
← →
XentaAbsenta (2008-04-15 11:48) [0]Сейчас я разрабатываю сервис для IRC, и из-за нехватки шаблонов и множественного наследования была даже мысль полностью пересесть на c++. Надо мной уже друзья смеются, называя меня шаблонизатором. Какие только трюки не приходится выкидывать чтобы не заниматься этим. Из-за нехватки этих фич код неимоверно распухает, хотя вполне можно было бы сделать его меньше. На самом деле HP разработала очень правильную библиотеку (STD), жаль, и очень жаль, что для делфей нет ничего подобного....
С нетерпением жду D2008.
← →
tesseract © (2008-04-15 11:55) [1]
> и из-за нехватки шаблонов и множественного наследования
> была даже мысль полностью пересесть на c++.
TInterfacedObject ?
ЗЫ : Почему просто классовую структурку не пририсовать хорошую ? Множественное наследование - палка о двух концах и одном геморое.
ЗЫ2 : А чего тут смешного, смеються те, кто две книжки проштудил и радуеться.
← →
Palladin © (2008-04-15 12:02) [2]
> XentaAbsenta (15.04.08 11:48)
разруха, она, знаете ли, в головах
сколько лет разрабатываю и только считаные разы у меня мелькнула мысль, а вот здесь бы множественное наследование бы, было бы очень красиво... а шаблоны, в общем то прекрасно все разрабатывается и без них...
← →
vuk © (2008-04-15 12:03) [3]TInterfacedObject не лечит ни от отсутствия множественного наследования (если нужно именно наследование функциональности) ни от отсутствия дженериков.
← →
Игорь Шевченко © (2008-04-15 12:11) [4]ерундой страдаете уважаемый
← →
oxffff © (2008-04-15 12:33) [5]
> vuk © (15.04.08 12:03) [3]
А что насчет делегирования реализации интерфейсу или объекту?
Механизм очень гибкий.
← →
vuk © (2008-04-15 12:43) [6]to oxffff © (15.04.08 12:33) [5]:
>А что насчет делегирования реализации интерфейсу или объекту?
А тут все просто. Делегирование - это не наследование. Причем, я согласен, множественное наследование - вещь, которая нужна крайне редко. Но заявлять о полной ненужность этой фичи, даже не имея под неё задач, не буду.
← →
oxffff © (2008-04-15 12:49) [7]
> А тут все просто. Делегирование - это не наследование.
Делегирование реализации полный аналог множественного наследования.
Приведите пример обратного.
Причем множественное наследование (которое вы привозносите :) ) имеет неприятный артифакт. А именно вызов виртуальной функции в конструкторе.
← →
Alkid © (2008-04-15 12:54) [8]
> XentaAbsenta (15.04.08 11:48)
Не слушай их всех, я тебя поддерживаю.
Шаблоны - хорошо, дженерики - почти так же хорошою, как шаблоны :)
Без них можно, с ними - лучше. Опять же, парадокс Блаба.
← →
vuk © (2008-04-15 13:01) [9]to oxffff © (15.04.08 12:49) [7]:
>Приведите пример обратного.
Нет уж, если так хочится примеров, то это Вы приводите пример того, что это полный аналог. :)
>которое вы привозносите :)
Я? Это хде? :)
← →
Игорь Шевченко © (2008-04-15 13:03) [10]oxffff © (15.04.08 12:49) [7]
> Делегирование реализации полный аналог множественного наследования.
А мужики и не знали
← →
Игорь Шевченко © (2008-04-15 13:04) [11]oxffff © (15.04.08 12:49) [7]
> (которое вы привозносите :) ) имеет неприятный артифакт
превозносите.
артефакт.
пардон, spellchecker сработал
← →
guav © (2008-04-15 13:06) [12]> была даже мысль полностью пересесть на c++.
ну так а почему нет, что за Delphi держит ?
← →
Alkid © (2008-04-15 13:17) [13]
> Делегирование реализации полный аналог множественного наследования.
Не совсем так.
Делегирование реализации аналогично ЗАКРЫТОМУ наследованию, когда новый класс является наследником, но не подтипом родителя. В этом смысле, делегирование нескольким классам аналогичено множественному закрытому наследованию, т.е:
class A : private B, private C
{
};
с точки зрения интерфейса аналогично
class A
{
private:
B& b_delegate;
C& c_delegate;
};
← →
vuk © (2008-04-15 13:21) [14]to Alkid © (15.04.08 13:17) [13]:
с точки зрения интерфейса аналогично
class A
{
private:
B& b_delegate;
C& c_delegate;
};
А это вообще агрегирование в чистом виде.
← →
Alkid © (2008-04-15 13:27) [15]
> А это вообще агрегирование в чистом виде.
И что? Одно другом не мешает! :)
← →
Slym © (2008-04-15 13:33) [16]нафег эти дженерики? лучшеб inline функции (функция, но по месту применения инлайнится без call) сделали, так их нехватает...
← →
Игорь Шевченко © (2008-04-15 13:35) [17]
> лучшеб inline функции (функция, но по месту применения инлайнится
> без call) сделали,
начиная с D2005 сделали.
← →
guav © (2008-04-15 13:39) [18]> [16] Slym © (15.04.08 13:33)
Чем лучше ? Кроме времени выполнения инлайн ни на что инлайн не влияет. А темплейты кое-что таки дают.
← →
Slym © (2008-04-15 14:16) [19]Игорь Шевченко © (15.04.08 13:35) [17]
начиная с D2005 сделали.
мдя... низнал... я сижу на 7 :), надо потестить как инлайнит
guav © (15.04.08 13:39) [18]
время иногда критично, особенно заметно - если вызываемая функция мала по размеру, но в цикле вызывается много раз
← →
oxffff © (2008-04-15 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 © (2008-04-15 14:34) [21]> мдя… низнал… я сижу на 7 :),
А ты думал, что если ты будешь долго сисдеть на D7, то туда добавят все что тебе надо? :)
← →
Игорь Шевченко © (2008-04-15 14:45) [22]
> Вы про ключевое слово implements в Delphi слышали?
И какое отношение это слово имеет к множественному наследованию ?
← →
jack128_ (2008-04-15 14:46) [23]
> время иногда критично, особенно заметно - если вызываемая
> функция мала по размеру, но в цикле вызывается много раз
ну инклюдь её руками, что мешает.
множественное наследование лично мне не нуно, а вот дженерики - было бы неплохо получить.
И моя личная мечта - анонимные функции и кортежи :-)
← →
oxffff © (2008-04-15 14:47) [24]
> Alkid © (15.04.08 12:54) [8]
>
> > XentaAbsenta (15.04.08 11:48)
>
> Не слушай их всех, я тебя поддерживаю.
> Шаблоны - хорошо, дженерики - почти так же хорошою, как
> шаблоны :)
> Без них можно, с ними - лучше. Опять же, парадокс Блаба.
>
Только generics поддерживает то, что принципиально нельзя в templates.
А именно инстанцирование шаблона Run time. :)
← →
Kolan © (2008-04-15 14:47) [25]> анонимные функции и кортежи :-)
А чей-то такое?
← →
Alkid © (2008-04-15 14:48) [26]
> Вы про ключевое слово implements в Delphi слышали?
Не, не слышал. На дельфи программировать закончил 1.5 года назад, и то была почти всё вермя пятёрка. Что это ключевое слово делает?
← →
oxffff © (2008-04-15 14:50) [27]
> Игорь Шевченко © (15.04.08 14:45) [22]
>
> > Вы про ключевое слово implements в Delphi слышали?
>
>
> И какое отношение это слово имеет к множественному наследованию
> ?
Это имеет отношение к
> Делегирование реализации аналогично ЗАКРЫТОМУ наследованию,
>
> когда новый класс является наследником, но не подтипом
>
> родителя.
Фактически никто не мешает обойтись и без Implements.
Только implements позволяет быстрее и эффективнее (функции обертки-делегирующие вызов не нужны).
← →
Palladin © (2008-04-15 14:51) [28]
> Alkid © (15.04.08 14:48) [26]
отделение мух от котлет при поддержке нескольких интерфейсов
← →
Alkid © (2008-04-15 14:53) [29]
> отделение мух от котлет при поддержке нескольких интерфейсов
Да, я уже прогуглил этот вопрос :)
Занятная штука. Страуструп, кстати, подобное задумывал в С++, но в итоге отказался. В принципе это - синтаксический сахар, но это ХОРОШИЙ синтаксический сахар.
← →
Игорь Шевченко © (2008-04-15 14:57) [30]oxffff © (15.04.08 14:50) [27]
Речь шла о том, что реализация интерфейсов - это не наследование.
← →
Alkid © (2008-04-15 15:01) [31]
> Речь шла о том, что реализация интерфейсов - это не наследование.
Формально - это не есть множественное наследование реализации. Но по сути даёт почти такие возможности, как и множественное наследование. А в чём-то даже по превосходит его. Так что я бы сказал, что с такой возможностью, идея множественного наследования реализации в НЕКОТРОЙ СТЕПЕНИ поддерживается в Дельфи.
← →
oxffff © (2008-04-15 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_ (2008-04-15 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 © (2008-04-15 15:12) [34]
> oxffff © (15.04.08 15:09) [32]
Занятственно :)
Более многословно, чем множественное наследование в С++, но более гибко, ибо позволяет в рантайме менять "родителей".
Интересно сравнить такую модель комбинации классов с тем, как это в С++ реализовано.
← →
oxffff © (2008-04-15 15:14) [35]
> Alkid © (15.04.08 15:01) [31]
Я бы сказал, что не уступает во всяком случае при грамотном использовании.
Фактически implements вставляет аналог делегирующей функции в виде в слот VMT интерфейса в виде подстройки смещения и перехода на реализацию.
← →
oxffff © (2008-04-15 15:16) [36]
> ибо позволяет в рантайме менять "родителей".
Ну на с++ тоже самое написать можно, но ручками. :)
← →
oxffff © (2008-04-15 15:19) [37]
> ибо позволяет в рантайме менять "родителей".
да и не забываем что семантика класса в С++ это value type (стек), а в Delphi это ref type(куча, неуправляемая :) ).
← →
Alkid © (2008-04-15 15:25) [38]
> oxffff © (15.04.08 15:14) [35]
Ну, что он куда вставляет - это технические детали :) Меня интересуют другие вещи.
Если рассматривать данный механизм, как инстумент построения архитектуры программы, то приходим к чему-то похожему на Smalltalk с его отдельным наследованием интерфейсов, т.е. основное дерево (граф?) наследования строится именно на интерфейсах (контрактах), а стоящие за ними реализации не обязаны образовывать некую стройную схему, возможно оставаясь фрагментарыми.
Вопрос для обсуждения - эта схема позволяет реализовывать миксины? Т.е. когда я пишу класс, реализующий *часть* интерфейса и скидываю на него реализацию этой части, беря реализацию оставшейся части из другого класса или определяя у себя? Очевидно, что такое можно реализовать, руками расписывая заглушки вида:
procedure TMyClass.MyMethod()
begin
delegate.MyMethod();
end;
Но это неудобственно. В принципе, виртуальное наследование в С++ решает подобную проблему. А тут как получается?
← →
Alkid © (2008-04-15 15:26) [39]
> > ибо позволяет в рантайме менять "родителей".
> Ну на с++ тоже самое написать можно, но ручками. :)
Да. Не хватает настоящего метапрограммирования в С++. И много где :)
> да и не забываем что семантика класса в С++ это value type
> (стек), а в Delphi это ref type(куча, неуправляемая :) ).
Гы. А указатели и ссылки для кого придуманы? :) И целый зоопарк смартпоинтеров туда же.
← →
oxffff © (2008-04-15 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 © (2008-04-15 15:32) [41]
> Гы. А указатели и ссылки для кого придуманы? :) И целый
> зоопарк смартпоинтеров туда же.
А что их тоже можно наследовать?
Я поэтому и написал, что это ручками.
← →
Alkid © (2008-04-15 15:32) [42]Т.е. это:
> procedure ContractB.MethodOfClassC=MethodOfClassCLocal;
Перекрывает это:
> property InstanceBRef:BCLASS read InstanceB implements ContractB;
да?
Симпатичненько получается.
← →
vuk © (2008-04-15 15:33) [43]oxffff © (15.04.08 14:32) [20]:
>Вы про ключевое слово implements в Delphi слышали?
Не только слышал но и использовал. И знаю, как оно работает. :)
to Alkid © (15.04.08 15:25) [38]:
>В принципе, виртуальное наследование в С++
>решает подобную проблему. А тут как получается?
Нет.
← →
oxffff © (2008-04-15 15:36) [44]
> Не только слышал но и использовал. И знаю, как оно работает.
> :)
Так привидите пример, что нельзя сделать в Delphi нельзя множественное наследование(подмешивание реализации с жизненным циклом совпадающим с агрегатом).
А я вам покажу как это сделать. :)
← →
Alkid © (2008-04-15 15:36) [45]
> Нет.
Что нет?
"Нет", в смысле, что тут никак не получается
или "Нет", в смысле, что виртуальное наследование в с++ не позвонляет использовать миксины?
← →
jack128_ (2008-04-15 15:37) [46]
> procedure MethodOfClassCLocal();procedure ContractB.MethodOfClassC=MethodOfClassCLocal;
кста, в старших дельфях(в 2007 по крайней мере) - есть глюки, связанные с такой конструкцией. Дельфя - никак не хотела понимать, что СontractB.MethodOfClassC реализуется методом MethodOfClassCLocal, а не тем классом, который в implements сидит.
← →
oxffff © (2008-04-15 15:42) [47]
> Alkid © (15.04.08 15:32) [42]
Более того можно менять семантику копирования агрегируемого RefCount, External RefCount, NoRefCount на лету. Все больше ничего не скажу (это мой секрет). :)
← →
Alkid © (2008-04-15 15:44) [48]
> Более того можно менять семантику копирования агрегируемого
> RefCount, External RefCount, NoRefCount на лету. Все больше
> ничего не скажу (это мой секрет). :)
Вах-вах!
Но вообще, скажем прямо, эта возможность выглядит в дельфи несколько инородно, учитывая что базовая библиотека классов опирается на традиционную гомогенную иерархию классов. Возникает ощущение, что либо "направление развития" языка сильно (кардинально) меняется, либо фитчи начинают добавлять вообще без всякой системы.
← →
oxffff © (2008-04-15 15:51) [49]
> Но вообще, скажем прямо, эта возможность выглядит в дельфи
> несколько инородно, учитывая что базовая библиотека классов
> опирается на традиционную гомогенную иерархию классов.
Наследование есть и остается одиночным. Но существуют способы расширить реализацию по другому.
>Вах-вах!
Полный Вах-вах был когда я этот свой код отлаживал в отладчике. :)
Потом нашел поменял две строчки местами и все заработало.
← →
Kolan © (2008-04-15 15:53) [50]> анонимные функции.
Понял, кажется такое есть в Ruby
← →
Kolan © (2008-04-15 15:54) [51]Кортежи (tuples)
Тоже понял. Вполне логичное название в рел. субд тоже используются.
ХЗ как все это может пригодится…
← →
Alkid © (2008-04-15 15:55) [52]
> Наследование есть и остается одиночным. Но существуют способы
> расширить реализацию по другому.
Дело в том, что этот механизм несколько "конкурирует" с наследованием. :)
Если брать выше, то он представляет собой серьёзную архитектурную альтернативу гомогенным иерархиям, которые традиционны для Дельфи.
ИМХО, дельфи теряет в стройности от этого.
← →
oxffff © (2008-04-15 16:00) [53]
> ИМХО, дельфи теряет в стройности от этого.
Время покажет. Судить не нам.
← →
vuk © (2008-04-15 23:45) [54]to Alkid © (15.04.08 15:36) [45]:
>Что нет?
>"Нет", в смысле, что тут никак не получается
Вопрос там был только один - получается ли такое в Delphi. Ответ ровно на него. Нет, не получается. Потому как наследование даёт новый интерфейс у порожденного класса, а делегирование - нет. Так что, если хочется работать с экземплярами классов, а не ссылками на интерфейсы, то вариант остается только один, тот самый, неудобственный.
to oxffff © (15.04.08 15:36) [44]:
>Так привидите пример, что нельзя сделать в Delphi нельзя множественное
>наследование(подмешивание реализации с жизненным циклом
>совпадающим с агрегатом).
Подмешивание реализации - можно. Множественное наследование - нет, т.к.
множественное наследование приводит к наследованию и интерфейса и реализации. В том же Вашем приведенном примере до методов можно добраться только через запросы интерфейсов, а не прямые вызовы методов у экземпляра.
>А я вам покажу как это сделать. :)
Я же говорю, что надо наоборот. Вы утверждаете, что делегирование - аналог множественного наследования. Вот и доказывайте. А мы посмотрим. :)
← →
ЦУП © (2008-04-16 02:54) [55]
> oxffff © (15.04.08 15:29) [40]
> > А тут как получается?Здесь очень хорошо это получается.
> А именно.ACLASS=classprocedure MethodOfClassA();end;BCLASS=classprocedure
> 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;protectedprocedure
> MethodOfClassCLocal();procedure ContractB.MethodOfClassC=MethodOfClassCLocal;
> property InstanceARef:ACLASS read InstanceA implements ContractA;
> property InstanceBRef:BCLASS read InstanceB implements ContractB;
> publicconstructor create;destructor destroy;override;end;
>
Вахвах... Зачем всё это?
Ну нет множественного наследования в Delphi.
Я бы с удовольствием воспользовался. но увы...
Пример.
Есть две фирмы - TFirm1 и TFirm2.
Способ взаимодействия с каждой - TInteraction1 и TInteraction2, соответственно.
Они производят одинаковый продукт. Одна Продукт1, вторая продукт2. Эти продукты отличаются только качеством. У одной фирмы процесс производства TProcess1, у второй - TProcess2.
Есть третья фирма, которая обединила обе. Хотелось бы не агрегированием, а прямым наследованием производить товары третьей фирмой.
> oxffff ©
А что, есть примеры реализации в наследниках каких либо классов(путь даже есть интерфейсы) множественного наследования?
В 32 и 40 всего лишь примеры агрегирования. Не так ли?
← →
ЦУП © (2008-04-16 02:57) [56]
> Alkid © (15.04.08 15:55) [52]
ИМХО, дельфи теряет в стройности от этого.
Delphi ничего не теряет.
То, что есть, то и есть.
В любом случае в Delphi всё реализуемо.
Вопрос возник из-за того, что не всё есть в Delphi.
← →
oxffff © (2008-04-16 09:29) [57]
> vuk © (15.04.08 23:45) [54]
> to Alkid © (15.04.08 15:36) [45]:
> >Что нет?
> >"Нет", в смысле, что тут никак не получается
> Вопрос там был только один - получается ли такое в Delphi.
> Ответ ровно на него. Нет, не получается. Потому как наследование
> даёт новый интерфейс у порожденного класса, а делегирование
> - нет. Так что, если хочется работать с экземплярами классов,
> а не ссылками на интерфейсы, то вариант остается только
> один, тот самый, неудобственный.
Да ну?
Делегирование реализации - это просто способ переноса ответственности по контракту или его части другому лицу (у которого жизненный цикл может, а может и не совпадать).
class(TinterfacedObject,ContractA,ContractB)
Таким образом вы объявляя, что класс поддерживает ContractA
и ContractB.
Если вам не нравится (по скорости) способ вызова через VMT интерфейса
ContractA метода.
А именно ContractA(A).MethodOfClassA;
То делайте так
A.InstanceARef.MethodOfClassA; <- (С++ делает тоже самое неявно за тебя).
Но у Delphi есть преимущество в том, что ты можешь настраивать перенос ответственности полностью или частично, также как и настраивать перенос ответственности по одному контракту на разные агрегаты.
> to oxffff © (15.04.08 15:36) [44]:
> >Так привидите пример, что нельзя сделать в Delphi нельзя
> множественное
> >наследование(подмешивание реализации с жизненным циклом
>
> >совпадающим с агрегатом).
> Подмешивание реализации - можно. Множественное наследование
> - нет, т.к.
> множественное наследование приводит к наследованию и интерфейса
> и реализации. В том же Вашем приведенном примере до методов
> можно добраться только через запросы интерфейсов, а не прямые
> вызовы методов у экземпляра.
Да не нужно нам множественное наследование,
НЕ НУЖНО В том виде как в С++. Мы еще ниже поговорим про артефакты
Добиваемся того же самого используя делегирование реализациии ( наследование это тоже самое по сути). И вы прекрасно знаете почему.
class classA: public ClassB, public ClassC Тоже самое что и
class classA
{
ClassB B;
ClassC C;
}
C той лишь разницей, что ClassB, ClassC scope натягивается на ClassA.
И при вызове компилятор за вас подстраивает Offset до агрегата.
Но не забываем, что не у вас возможности просто менять часть реализации.
A.InstanceARef.MethodOfClassA;
← →
Игорь Шевченко © (2008-04-16 09:34) [58]oxffff © (16.04.08 09:29) [57]
> Да не нужно нам множественное наследование,
> НЕ НУЖНО В том виде как в С++. Мы еще ниже поговорим про
> артефакты
Это вам не нужно. Не надо говорить за всех.
← →
oxffff © (2008-04-16 09:41) [59]В этом примере.
class classA
{
public:
virtual void MethodA() {};
};
class classB
{
public:
virtual void MethodB() {};
};
class classC: public classA , public classB
{
//virtual void MethodB() {};
};
classC содержит два агрегата classA, classB.
Также как и два vfptr у каждого агрегата.
Хотите поговорить про артефакты (затраты на вызов при виртуальном наследовании) в С++. А именно про indirect обращение через
virtual base pointer(s) (vbptr)?
← →
oxffff © (2008-04-16 09:43) [60]
> Игорь Шевченко © (16.04.08 09:34) [58]
> oxffff © (16.04.08 09:29) [57]
>
>
> > Да не нужно нам множественное наследование,
> > НЕ НУЖНО В том виде как в С++. Мы еще ниже поговорим про
>
> > артефакты
>
>
> Это вам не нужно. Не надо говорить за всех.
Ну насколько я знаю вам это не нужно. Не так ли?
← →
Игорь Шевченко © (2008-04-16 10:01) [61]oxffff © (16.04.08 09:43) [60]
Иногда бывает нужно и берет досада, что нету.
← →
oxffff © (2008-04-16 10:12) [62]
>
> Игорь Шевченко © (16.04.08 10:01) [61]
> oxffff © (16.04.08 09:43) [60]
>
> Иногда бывает нужно и берет досада, что нету.
Для того чтобы достичь цели не нужно его вводить.
Привидите пример когда у вас эта возникла и почему?
И что вам мешало и ограничивало в Delphi?
← →
Игорь Шевченко © (2008-04-16 10:23) [63]oxffff © (16.04.08 10:12) [62]
> Для того чтобы достичь цели не нужно его вводить.
Я понимаю, я же выхожу из положения. Но неудобно.
> Привидите пример когда у вас эта возникла и почему?
А смысл ? Решение найдено существующими средствами, собственно и не одно. Можно же вообще обходиться без наследования, как множественного, так и одиночного, можно обходиться без инкапсуляции и полиморфизма, все будет работать, уверяю.
← →
oxffff © (2008-04-16 10:24) [64]
> Игорь Шевченко © (16.04.08 10:01) [61]
> oxffff © (16.04.08 09:43) [60]
>
> Иногда бывает нужно и берет досада, что нету.
Есть предположение, что если его ввести (а я остаюсь при мнении что это не нужно) это напрочь поломает структуру Tobject.
Какое решение принимать при вызове AfterContruction и BeforeDestruction.
Делать автоматом или как?
Далее как решать конфликт Idx при вызове динамических методов.
и я уверен это еще не все.
Я конечно уверен что это все решаемо.
← →
oxffff © (2008-04-16 10:30) [65]
> собственно и не одно.
И я о том же.
← →
oxffff © (2008-04-16 10:35) [66]
> Я понимаю, я же выхожу из положения. Но неудобно.
Может вы не так что то делаете?
← →
vuk © (2008-04-16 10:54) [67]to oxffff © (16.04.08 09:29) [57]:
>Если вам не нравится (по скорости) способ вызова через VMT интерфейса
>ContractA метода.
>А именно ContractA(A).MethodOfClassA;
>То делайте так
>A.InstanceARef.MethodOfClassA;
Фтопку. Ибо нарушение инкапсуляции.
← →
Игорь Шевченко © (2008-04-16 11:02) [68]
> (а я остаюсь при мнении что это не нужно)
да и одиночное наследование тоже как бы не особенно к чему.
← →
oxffff © (2008-04-16 11:26) [69]
> vuk © (16.04.08 10:54) [67]
> to oxffff © (16.04.08 09:29) [57]:
>
> >Если вам не нравится (по скорости) способ вызова через
> VMT интерфейса
> >ContractA метода.
> >А именно ContractA(A).MethodOfClassA;
>
> >То делайте так
> >A.InstanceARef.MethodOfClassA;
> Фтопку. Ибо нарушение инкапсуляции.
Вы просто не имеете их готовить.
Где нарушение инкапсуляции?
Доступ к членам A.InstanceARef согласно области видимости
Private, protected, public класса объекта InstanceARef.
А что касается ContractA(A).MethodOfClassA так вы определите public подмножество ContractA.
Не надо натягивать идеалогию видимости из С++ на Delphi.
← →
vuk © (2008-04-16 11:42) [70]to oxffff © (16.04.08 11:26) [69]:
>Вы просто не имеете их готовить.
А вот это уже не Вам судить. Ага? :)
>Где нарушение инкапсуляции?
В Вашем же примере свойство InstanceARef имеет область видимости protected. Стало быть клиенту не доступно и пока всё нормально. Но вот если есть желание вызывать как A.InstanceARef.MethodOfClassA, то нужно делать public. Что открывает доступ клиенту к тому, к чему, по-хорошему, у него доступа быть не должно.
← →
oxffff © (2008-04-16 12:02) [71]
> vuk © (16.04.08 11:42) [70]
> to oxffff © (16.04.08 11:26) [69]:
> >Вы просто не имеете их готовить.
> А вот это уже не Вам судить. Ага? :)
>
> >Где нарушение инкапсуляции?
> В Вашем же примере свойство InstanceARef имеет область видимости
> protected. Стало быть клиенту не доступно и пока всё нормально.
> Но вот если есть желание вызывать как A.InstanceARef.MethodOfClassA,
> то нужно делать public. Что открывает доступ клиенту к
> тому, к чему, по-хорошему, у него доступа быть не должно.
>
Судить не мне. Мне это не нужно. Однако хочу отметить
> Но вот если есть желание вызывать как A.InstanceARef.MethodOfClassA,
> то нужно делать public. Что открывает доступ клиенту к
> тому, к чему, по-хорошему, у него доступа быть не должно.
>
Я так понимаю есть желание у составного объекта сделать вызов у агрегата?
Так определите их в одном модуле.
Либо сделайте public, а составном объекте (в примере так и сделано) в protected.
protected
property InstanceARef:ACLASS read InstanceA implements ContractA;
Таким образом все согласно идеалогии Delphi.
← →
Игорь Шевченко © (2008-04-16 12:04) [72]
> Так определите их в одном модуле.
Проще сделать все public
← →
vuk © (2008-04-16 12:16) [73]to oxffff © (16.04.08 12:02) [71]:
>Я так понимаю есть желание у составного объекта сделать вызов у
>агрегата?
Речь вообще не о том. Попробую объяснить немного иначе. Я хочу сказать, что множественное наследование помимо наследования реализации приводит к формированию некоего нового контракта на основе нескольких исходных контрактов. И при этом клиент может ничего не знать об исходных. С интерфейсами все обстоит иначе. Никакого нового контракта не возникает и клиент оперирует исходными контрактами. Так понятнее?
И именно поэтому тот прием с mix-in из C++ аналога в Delphi не имеет.
← →
oxffff © (2008-04-16 12:43) [74]
> Речь вообще не о том. Попробую объяснить немного иначе
Ну судя по
>вот если есть желание вызывать как A.InstanceARef.MethodOfClassA,
> то нужно делать public.
Как как раз о том.
Теперь ответ на ваш новый вопрос.
Действительно компилятор не обрабатывает конструкцию вида
procedure ContractD.MethodOfClassC=InstanceB.InstanceBRef;
Для наследования от двух решение есть. наследуете от одного, делегируете второму с общим контрактом.
ContractD=interface
["{F283C2A5-05A9-4772-A0FB-46CE18C74218}"]
procedure MethodOfClassC();
procedure MethodOfClassB();
procedure MethodOfClassA();
end;
Для трех и более компилятор не поддерживает конструкцию вида
procedure ContractD.MethodOfClassC=InstanceB.InstanceBRef;
Однако ее можно написать самому. и сделать метод Inline.
Либо написать в Codegear. Нужно слегка поправить синтаксис.
Не принципиально.
← →
oxffff © (2008-04-16 14:17) [75]
> Речь вообще не о том. Попробую объяснить немного иначе.
> Я хочу сказать, что множественное наследование помимо наследования
> реализации приводит к формированию некоего нового контракта
> на основе нескольких исходных контрактов. И при этом клиент
> может ничего не знать об исходных. С интерфейсами все обстоит
> иначе. Никакого нового контракта не возникает и клиент оперирует
> исходными контрактами. Так понятнее?
После обеда у меня вот какие мысли.
Вы говорите об общем контракте производного типа. Поэтому для использования этого контракта клиенты должны знать об этом типе(либо его производных).
В таком случае возникает вопрос, если клиент использует конкретный тип (либо производные от него), если какая то разница использовать общий контракт или котракты разделенные по функциональности?
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2008.06.01;
Скачать: [xml.tar.bz2];
Память: 0.69 MB
Время: 0.041 c