Форум: "Потрепаться";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
ВнизВот спорю с коллегой на работе, подскажите есть ли множественное Найти похожие ветки
← →
Гаврила © (2004-08-10 12:31) [40]
> Игорь Шевченко © (10.08.04 12:21) [37]
Создать class1 надо конечно, поскольку он является полем class2, то и создать его логично в конструкторе class2. Вот и весь код. НУ а передавать ли ему ссылку на class1 - от задачи зависит :-)
← →
Игорь Шевченко © (2004-08-10 12:33) [41]Romkin © (10.08.04 12:24) [38]
> А если еще учесть, что при использовании интерфейсов есть
> возможность агрегировать в себя (читай - унаследовать) всю
> функциональность класса, написанного на другом языке, то
> становиться понятным, почему я говорю, что множественное
> наследование классов устарело :))
Множественность-то здесь причем ? Вся эта фраза точно также относится и к одиночному наследованию.
> А при использовании интерфейсов таких тонкостей просто нет.
> И более того, с интерфейсами для того, чтобы твой класс
> воспринимался как предок, ты не обязан порождать свой класс
> от предка, можно просто реализовать его интерфейс. Так,
> как хочется.
Дублируя код предка, если требуется его функциональность ? :))
> Простой пример: у предка есть виртуальный метод, наследник
> его перекрывает, но не вызывает в нем inherited, собственно
> метод предка. Допустимо ли это технологией? Конечно. Но
> ведь потомок не знает, что делает метод предка, который
> он не вызвал. А он может делать что-то, затрагивающее функциональность
> предка, да хоть количество его вызовов подсчитывать :) Вот
> и получается, что программист, написав потомок, вторгся
> в логику работы предка, и изменил ее!
Опять же, причем тут именно множественное наследование ? Все это точно так же может быть отнесено к одиночному наследованию, однако его, почему-то ничкто не отменяет и не пишет, что оно устарело :))
← →
Игорь Шевченко © (2004-08-10 12:34) [42]Romkin © (10.08.04 12:30) [39]
> Создавать придется. Но перенаправлять ничего не надо, все,
> что нужно агрегату, это IUnknown class2. А это предусмотрено,
> см CoCreateInstance, параметр pUnkOuter
Я вообще-то не про COM...Я вообще-то про обычное использование интерфейсов и наследование...Я в COM не так силен, как ты :)
← →
DiamondShark © (2004-08-10 12:35) [43]Дело в том, что наследование и реализация интерфейсов -- разные по назначению вещи.
Наследование -- инструмент повторного использования кода.
Интерфейсы -- инструмент структурирования предметной области, задачи, модели.
← →
Игорь Шевченко © (2004-08-10 12:36) [44]Гаврила © (10.08.04 12:31) [40]
> Создать class1 надо конечно, поскольку он является полем
> class2, то и создать его логично в конструкторе class2.
> Вот и весь код. НУ а передавать ли ему ссылку на class1
> - от задачи зависит :-)
Только вот я не совсем понимаю, чем это лучше, чем множественное наследование ? :)
← →
Гаврила © (2004-08-10 12:39) [45]
> Игорь Шевченко © (10.08.04 12:36) [44]
Да это и не лучше, просто нет его, множественного наследования у нас :-)
← →
Romkin © (2004-08-10 12:40) [46]Игорь Шевченко © (10.08.04 12:33) [41] При том, что оно становиться не нужным :)))
А одиночное - можно обойтись и без него, но оно удобно. А главное - достаточно.
>Дублируя код предка, если требуется его функциональность ? :))
Вот именно. Ты можешь унаследовать предка, можешь его агрегировать, а можешь продублировать его фукнциональность :)
На выбор. И при этом пользователь твоего потомка просто не догадается, как именно ты сделал :)))
Более того, пользователь часто вообще не знает, как и где именно реализован данный интерфейс ;)
← →
Игорь Шевченко © (2004-08-10 13:08) [47]DiamondShark © (10.08.04 12:35) [43]
> Наследование -- инструмент повторного использования кода.
Игорь Шевченко © (10.08.04 10:09) [10]
> Мне, например, из-за его отсутствия приходится писать лишний > код. Иногда напрягает
:)
Romkin © (10.08.04 12:40) [46]
> А одиночное - можно обойтись и без него, но оно удобно.
> А главное - достаточно.
Честно говоря, не понимаю :)
> Вот именно. Ты можешь унаследовать предка, можешь его агрегировать,
> а можешь продублировать его фукнциональность :)
Собственно говоря, введение множественного наследования не мешает мне сделать те же три действия :)
> Более того, пользователь часто вообще не знает, как и где
> именно реализован данный интерфейс
Какой пользователь имеется в виду ?
← →
Антон (2004-08-10 13:16) [48]Я вообще-то в Delphi не секу, пишу на С++, а этот форум зинтересовал меня по простой причине, хочу понять, есть ли объективые причины почему в Delphi не реализовано множественное наследование. Я исключаю ответы типа устарело, излишне, приводит к ошибкам. Основной вопрос - может ли это быть связано с различием в процессах распеделения памяти и т.п.
А вообще множественное наследование легко реализуется простым вложением двух объектов различных классов в качестве членов третьего, далее остается только предоставить код, возвращающий адреса этих объетов. Так например:
class A { };
class B { };
class C : public A, public B { };
экивалентно
class C { A a; B b; }
← →
Игорь Шевченко © (2004-08-10 13:22) [49]
> А вообще множественное наследование легко реализуется простым
> вложением двух объектов различных классов в качестве членов
> третьего, далее остается только предоставить код, возвращающий
> адреса этих объетов. Так например:
>
>
> class A { };
> class B { };
>
> class C : public A, public B { };
> экивалентно
> class C { A a; B b; }
Не эквивалентно. Класс C не может быть представлен ни как класс A, ни как класс B
← →
Антон (2004-08-10 13:29) [50]Хорошо, продолжу:
struct A {};
struct B {};
struct C {
A a; B b;
operator A* () { return &a; }
operator B* () { return &b; }
};
void f()
{
C c;
A* p_a = c;
B* p_b = c;
cout << p_a << " " << p_b << " " << &c << endl;
}
В результате видим примерно следующее:
0012FF74 0012FF78 0012FF74
Это аблолютная аналогия.
← →
Игорь Шевченко © (2004-08-10 13:46) [51]
> В результате видим примерно следующее:
> 0012FF74 0012FF78 0012FF74
> Это аблолютная аналогия.
???????????????????? Эт как ?
← →
Piter © (2004-08-10 13:57) [52]Игорь Шевченко © (10.08.04 10:09) [10]
Мне, например, из-за его отсутствия приходится писать лишний код. Иногда напрягает
а можно пример, когда множественное наследование полезно?
← →
Антон (2004-08-10 13:58) [53]> ???????????????????? Эт как ?
Аналогичный результат я получу если просто напишу класс С при помощи синтаксиса множественного наследования, как показывал выше. Дело в том, что память распределится идентичным образом в обоих случаяю, поэтому разницы никакой нет.
← →
Антон (2004-08-10 14:02) [54]> а можно пример, когда множественное наследование полезно?
Есть такой мультик - КОТОПЕС, а если серъезно, то любое моделирование гибридных объектов.
← →
Piter © (2004-08-10 14:46) [55]Антон (10.08.04 14:02) [54]
нет, мне бы пример. Например, постановка задачи и путь ее реализации. Желательно в терминах Delphi
Например, нечто реализовывается так. Но вот если было бы множественное наследование - то это можно было бы реализовать гораздо проще, потому что...
← →
DiamondShark © (2004-08-10 14:51) [56]
> то любое моделирование гибридных объектов.
Агрегирование.
← →
Игорь Шевченко © (2004-08-10 14:59) [57]
> Аналогичный результат я получу если просто напишу класс
> С при помощи синтаксиса множественного наследования, как
> показывал выше. Дело в том, что память распределится идентичным
> образом в обоих случаяю, поэтому разницы никакой нет.
Это зависит от конкретной реализации языка, не так ли ?
Синтаксис наследования является стандартом языка, в то время, как распределение памяти стандартом отнюдь не является.
← →
Антон (2004-08-10 15:43) [58]
> Это зависит от конкретной реализации языка, не так ли ?
> Синтаксис наследования является стандартом языка, в то время,
> как распределение памяти стандартом отнюдь не является.
Вот это меня и интерисует, я как абсолютный профан в Delphi, не знаю можно ли аналогично реализовать множественное наследование посредством агрегации, как я показал на примере с С++. Это был пример для обсуждения и не больше. Что мешает реализовать аналогично множественное наследование в Delphi, вот в чем вопрос? Ведь у вас есть простое наследование, нет операторов преобразования типа как в С++, но их можно заменить и на обычные ф-ии члены класса (воспрос синтаксиса)?
← →
Антон (2004-08-10 15:50) [59]
> нет, мне бы пример. Например, постановка задачи и путь ее
> реализации. Желательно в терминах Delphi
>
> Например, нечто реализовывается так. Но вот если было бы
> множественное наследование - то это можно было бы реализовать
> гораздо проще, потому что...
Прости, в терминах Delphi не могу, просто не знаю, да и дело не в терминах. Я могу привести пример реализации библиотеки Motif. Она не относится к вопросу о множественном наследовании. Но она эмулирует C++ в части скрытия данных и разграничения доступа, хотя это чисто С библиотека. Можно использовать средства языка для эмуляции средств не реализованных в языке, но проще пользоваться синтаксисом заложенным изначально в язык, по моему это удобнее.
← →
Игорь Шевченко © (2004-08-10 15:51) [60]
> Вот это меня и интерисует, я как абсолютный профан в Delphi,
> не знаю можно ли аналогично реализовать множественное наследование
> посредством агрегации, как я показал на примере с С++.
Я имел в виду, что в различных реализациях одного языка (С++) реализация может быть разная.
← →
Антон (2004-08-10 16:09) [61]
> Я имел в виду, что в различных реализациях одного языка
> (С++) реализация может быть разная.
Понял твой намек. Дело в том что модесь COM, которая упоминалась в форуме реализуется именно с помощью агрегации, спорить с этим бесполезно. Так на чем же она основывается? Ответ очевиден. Что-бы предоставить доступ к интерфейсу, не использую конструкции C++, приходится эмулировать его с помощью агрегации...
← →
Mystic © (2004-08-10 16:18) [62]Вот пример. Есть библиотека где представлены различные классы (со своей иерархией наследования), в том чсле TSomeClass. Допустим, эту библиотеку мы изменять не можем. В определенный момент равития системы (пишется компонет, имеюший published свойство типа TSomeClass). Нам надо чтобы этот класс был порожден от TPersistent и умел сохраняться в поток, присваиваться и т. д.
← →
Антон (2004-08-10 16:28) [63]
> Я имел в виду, что в различных реализациях одного языка
> (С++) реализация может быть разная.
Я думаю, ты понял, что проблема не в реализации компилятора, а в том, что компилятор для Object Pascal невозможно реализовать аналогично, что именно мешает мне и интересно, возможны варианты, один из которых - однопроходность, но это только для затравки...
← →
Игорь Шевченко © (2004-08-10 16:30) [64]
> Я думаю, ты понял, что проблема не в реализации компилятора,
> а в том, что компилятор для Object Pascal невозможно реализовать
> аналогично, что именно мешает мне и интересно, возможны
> варианты, один из которых - однопроходность
Однопроходность здесь ни с какого боку, вроде...
Ничего не мешает реализовать компилятор с Паскаля, который будет поддерживать множественное наследование.
← →
Cobalt © (2004-08-10 16:49) [65]2 Mystic © (10.08.04 16:18) [62]
Минуточку - тут имеет место небольшое лукавство:
Если это компонент (для формы/ДатаМодуля) - он уже наследуется от TPersistent - и это упрощает дело
Если же это просто класс - то это уже не проблема вызвать у него метод SaveToStream самому (на мой взгляд).
← →
Игорь Шевченко © (2004-08-10 17:02) [66]
> Если же это просто класс - то это уже не проблема вызвать
> у него метод SaveToStream самому (на мой взгляд).
А если его нету ?
← →
Антон (2004-08-10 17:17) [67]
> > Если же это просто класс - то это уже не проблема вызвать
> > у него метод SaveToStream самому (на мой взгляд).
> А если его нету ?
Причем метод которого нету, можно конечно реализовывать "ЖИРНЫЙ" интерфейс, который предусматривает чисто фиртуальные метомы (в вашем понимании интерфейсы), обеспечивая совместимость на уровне вызова ф-ий членов, но для чего? Елсли нет возможности преобразовать тип во время исполнения в производный, только тогда возможен изврат с ЖИНЫМ интерфейсом (а как на счет производных классов которые в приципе не могут реализовать данный интерфейс..., что делать заглушки...?)
← →
Cobalt © (2004-08-10 17:52) [68]Хм..
Есть класс (TParent1), который изменять нельзя. Порождён не от TMyClass1.
Надо: Добавить ему функционал этого TParent2.
Решение 1: Без использования множественного наследования
Добавляем в новый класс(TChild) поле типа TParent2. Устанавливаем его свойства, обработчики и т.п. Везде, где надо, суём поле, а не сам класс (TChild).
+ Хорошо, если этот функционал не должен затрагивать функционал и поля TParent1.
- Плохо, если необходимо чтобы новый функционал работал с полями исходного класса TParent1 как со своими собственными
Решение 2: С использованием множественного наследования
Добавляем в новый класс(TChild) родителя типа TParent2. У него появляются новые поля и методы для исполнения соответствующего функционала.
Вопрос - как TParent2 должен взаимодействовать с Методами и Полями другого TParent1 в TChild?
← →
Cobalt © (2004-08-10 17:53) [69]Я как-то пока себе не представляю.
← →
Cobalt © (2004-08-10 18:08) [70]Ещё - если функционал TParent2 должен работать с полями TParent1, то в TChild надо переписывать эти методы.
Выигрыш - TChild на вопросis TParent1
ответит True, и позволит работать с классом, как с TParent1.
P.S.
Cobalt © (10.08.04 17:52) [68]
Следует читать:
Есть класс (TParent1), который изменять нельзя. Порождён не от TParent2.
Надо: Добавить ему функционал этого TParent2.
← →
Romkin © (2004-08-10 18:13) [71]Бррр. Ну что вы маетесь?! Я вообще уже ничего не понимаю.
В Delphi нет множественного наследования классов. Оно не обязательно.
Но если очень хочется - есть множественное наследование интерфейсов, и пользоваться им гораздо приятнее :)
Например, можно создать потомка на Delphi от класса, написанного на С++ Ж-)
← →
Cobalt © (2004-08-10 18:26) [72]просто меня тоже заинтересовало - были ли какие-то объективные причины для того, что бы не реализовывать множественное наследование в Delphi? Или просто решили, мол, нафиг это не надо, не будем с этим заморачиваться, и вообще это непопулярно, и забили на этом жирный крест.
← →
Romkin © (2004-08-10 18:35) [73]Естественно, просто решили.
Надо будет - введут. Но лучше не надо :)
← →
Cobalt © (2004-08-10 19:49) [74]Отчего же?
Довольно-таки удобно, компилятор будет ругаться на вызов метода без указания его родителя (при наличии нескольких одноимённых у разных предков), все будут довольны :)
← →
Бином Ньютоныч (2004-08-10 19:54) [75]Причины, имхо, вполне конкретые. Множ. наследование - бред бушевноболдьного. Два - три этапа - и в эторм классе сам черт со страуртруппом не разберутся, не говоря уж про нас, бедных...:(
← →
Бином Ньютоныч (2004-08-10 19:57) [76]Про компилятор я вообще молчу. Как он из этого хоть иногда вылазит - загадка природы, достойная пера Дема-отца.
← →
Cobalt © (2004-08-10 20:56) [77]2 Бином Ньютоныч (10.08.04 19:54) [75]
Ну, не скажите. Если программист запутался втом, что же делает (может делать) его класс - это его проблема. при строгом непересекающемся наследовании я не вижу проблем составить карту методов и полей, унаследованных от всех его родителей.
Единственная проблема, которую я углядел - конфликт Published-свойств у компонентов - как их отображать? сохранить в dfm?
Загружать из dfm? Вот это, кажется - самое трудное - пришлось бы, наверное, добавлять в RTTI данные о классах и их Published-свойствах - для того, что бы можно было выбирать. Типа
GetParentClass(Parent1Name).SetProperty(PropertyName1).AsString
P.S. Я пробовал смотреть исходники TReader, но, честно говоря, не понял - где же он устанавливает значение Published-свойств?
← →
Бином Ньютоныч (2004-08-10 21:32) [78]>Cobalt © (10.08.04 20:56) [77]
Извините, но большая часть Вашей работы - это использование чуого кода(VCL) И это здорово, я не против:)
Да нет, Вы просто попробуйте построить иерархию со множественным наследованием. Ничего сложного не используйте, все обыденно: источник данных, обраьотчик коллизий, интерфейс юзера... Потом сделайте еще шаг - администратор. Потом Вам(юзеру) захочется быть супервизором. А кому не хочется - всем хочется. Но мы не позволим, мы умные, видали уже. Однако заказчик настаивает. Ладно, Вы обговорили бабки, но слабина уже есть! Он захочет большего, причем в рамках. Откажешь? Дудки, это же клиент, деньги, жизнь... А дальше? Ну сколько ты будещь расширять функ. в рамках языка? А когда выйдет за рамки? Но это все хрень. Что мне ДЕЙСТВИТЕЛЬНО непонятно - как ты будешь обеспечивать БЕЗОПАСНОСТЬ всей этой хрени? Поделись:)
← →
Cobalt © (2004-08-10 21:47) [79]Я чувствую, ты что-то хочешь сказать мне, что-то наболевшее...
Но вот что - я никак не пойму.
← →
Cobalt © (2004-08-11 17:37) [80]Может, ещё какие есть объективные причины для отсутствия множественного наследования?
Страницы: 1 2 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
Память: 0.64 MB
Время: 0.039 c