Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.156] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 191 192 [193] 194 195 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#2881
,
|
|
|
|
|
Сообщ.
#2882
,
|
|
|
|
Цитата MyNameIsIgor @ А первое без второго что ли бывает? Я не случайно вытащил отдельно второе понятие |
|
Сообщ.
#2883
,
|
|
|
|
Цитата DesweR @ Я не случайно вытащил отдельно второе понятие ![]() Ах, вы хотели показать, что знаете это слово... Ну, ладно, понял. |
|
Сообщ.
#2884
,
|
|
|
|
Цитата trainer @ И что там по поводу перечисления признаков, по которым в C++ "Объект - набор предков. Это и выглядит как набор предков, и работает так же, по внешним признакам." Удобство и современность - это прежде всего понимание того, что объект - не стуктура с виртуальными методами, подчиняющаяся правилам для структура, но абстракция со своими уникальными свойствами. По поводу набора предков. Попробую объяснить. В С++ объект это фактически структура, при создании вызываются конструкторы всех предков, причем каждый конструктор фактически работает с объектом именно как с предком, с поведением и данными предка. Уже это однозначно указывает на факт набора предков. Второе - именно свободное копирование при передаче по значению, когда потомок копируется в предка. Могу сразу сказать, что у дельфиста от такого волосы встают дыбом Со структурой-то все понятно, там только данные. А вот класс - сложная конструкция, даже если бы не по ссылке - все равно не скопируешь. Дело в том, что в Delphi все подчиняется правилам языка. Компилятор тоже "Compiler magic" - это тоже библиотечный код, написанный на Delphi. Поэтому, в частности, доступа к приватной секции снаружи нет. То есть копирование класса компилятором - это явное и грубое нарушение правил инкапсуляции. По крайней мере, так считается в Delphi. В новых версиях, 2009 и новее, у программиста есть возможность указать генерацию RTTI для приватных членов класса, что позволяет это осуществить (с заметными накладными расходами), причем грамотно. Исторически у программиста Delphi есть власть полностью отрубить потомка от предка. Вообще, потомок - самостоятельная сущность, которая просто может использовать код и данные предка. А может и не использовать... Цитата trainer @ Особенно удобен и модернов модификатор dynamic в классах Delphi. Кстати, каковы критерии удобства и современности? Модификатор dynamic удобен, в некоторых случаях. Критерии удобства и современности просты: 1. Метакласс и метапрограммирование: тип объекта тоже объект. 2. RTTI: полная информация об объекте, объем которой контролируется программистом. С возможностью обмена этой информацией отдельно от собственно объекта. 3. Прямая поддержка типа "метод объекта": методы как поля данных. Нам не нужно извращаться, чтобы написать ![]() ![]() if assigned(FOnClick) then FOnClick(Self); 4. Разделение на структуры, классы и интерфейсы, с четким разделением функций и контролем на уровне языка. Когда класс - просто структура можно сказать, что интерфейс - абстрактный класс. Но объект не должен быть структурой, а структура - объектом. Это разные абстракции, и они должны быть разделены. Программирование должно быть защищенным: написанное должно иметь смысл. Какой смысл в передаче объекта с виртуальными методами по значению предка? Брр. 5. Наличие дженериков с контрактными объявлениями, то есть шаблонов с четким контролем контракта объекта. |
|
Сообщ.
#2885
,
|
|
|
|
Цитата korvin @ Цитата D_KEY @ Если мы меняем объект через y, должен ли меняться объект, доступный через x? На мой взгляд, это должно зависить лишь от правил, принятых в языке для переменных. На твой, как я понимаю, это должно зависить от типа? Так? зависит от типа и только. что если я присвою y 1) иммутабельнцю структуру? (хотя это "ссылочная переменная", ибо передается по ссылке)? 2) иммутабельную структуру, у которой одно из полей -- мутабельная структура? 3) мутабельную структуру, у которой одно из полей -- иммутабельная структура? как тебе твоя "семантика переменных" поможет? Объясни, причем тут реализация типа? Я не против передачи по ссылке, я не против реализации типа таким образом, чтобы он внутри содержал ссылку. Я против неявно-ссылочных типов. И почему ты всегда отвечаешь вопросом на вопрос? Мне надоело задавать один и тот же вопрос в сотый раз, пытаясь его перефразировать, чтобы ты наконец понял, на что нужно ответить. Вот и сейчас ты говоришь, что зависит от типа, а пример приводишь уже из другой оперы. Добавлено Немного не в тему нашего с korvin'ом разговора. Исходя из твоих же(и не только) ответов в соседней теме следует, что переменные классов всегда являются ссылками(в отличие от остальных) и что присваивание одной переменной другой будет происходит по ссылке в любом случае, как бы ты не переопределял операторы. Это не так? |
|
Сообщ.
#2886
,
|
|
|
|
Цитата Romkin @ RTTI: полная информация об объекте, объем которой контролируется программистом. С возможностью обмена этой информацией отдельно от собственно объекта. Удобство безусловно, но почему это должно быть реализовано на уровне языка/компилятора а не фреймворка или библиотеки? |
|
Сообщ.
#2887
,
|
|
|
|
Цитата Romkin @ Программирование должно быть защищенным: написанное должно иметь смысл. Какой смысл в передаче объекта с виртуальными методами по значению предка? Брр. Вот именно что никакого, и автор этого кода просто допустил ошибку, это тоже самое, что в Делфи, вместо того чтобы разъименовать объект, не разименуют его... |
|
Сообщ.
#2888
,
|
|
|
|
Цитата Romkin @ Удобство и современность - это прежде всего понимание того, что объект - не стуктура с виртуальными методами, подчиняющаяся правилам для структура, но абстракция со своими уникальными свойствами. Согласен. А в Delphi даже с конструированием большие проблемы... Цитата По поводу набора предков. Попробую объяснить. В С++ объект это фактически структура, при создании вызываются конструкторы всех предков, причем каждый конструктор фактически работает с объектом именно как с предком, с поведением и данными предка. Уже это однозначно указывает на факт набора предков. Нет. Объект является экземпляром не только своего класса, но и всех предков. Поэтому конструкторы должны вызываться(для того, чтобы объект соответствовал экземпляру каждого из этих классов, а это гарантируется конструкторами и только ими - никто другой не знает как это делать), ведь речь идет не об интерфейсе, а о классах. Цитата Второе - именно свободное копирование при передаче по значению, когда потомок копируется в предка. Могу сразу сказать, что у дельфиста от такого волосы встают дыбом От этого встают волосы дыбом не только у Delphi'цев. Сколько можно обсуждать? Язык позволяет это по той простой причине, что правила для пользовательских типов не должны отличаться от правил для встроенных. В противном случае получаем кривую систему типов, где куда не плюнь - свои правила. Цитата у программиста Delphi есть власть полностью отрубить потомка от предка. Такая власть есть у любого программиста - нужно просто не наследовать Цитата Вообще, потомок - самостоятельная сущность, которая просто может использовать код и данные предка. А может и не использовать... Зачем тогда использовать наследование? Это кривой дизайн. Если тебе нужен лишь интерфейс базового класса, то и создай интерфейс(абстрактный класс) и унаследуюся от него в обоих случаях. Зачем язык толкает на неверные проектные решения? |
|
Сообщ.
#2889
,
|
|
|
|
Цитата Romkin @ Исторически у программиста Delphi есть власть полностью отрубить потомка от предка. Вообще, потомок - самостоятельная сущность, которая просто может использовать код и данные предка. А может и не использовать... ![]() ![]() #include<iostream> class Base { public: virtual void Method(){std::cout<<"Base";} }; class Derive:private Base { public: void Method(){std::cout<<"Derive";} }; void Func(Base b) { b.Method(); } int main() { Derive d; Func(d); } ![]() ![]() poly_test.cpp: In function 'int main()': poly_test.cpp:23:9: error: 'Base' is an inaccessible base of 'Derive' poly_test.cpp:15:6: error: initializing argument 1 of 'void Func(Base)' "It's a kind of magic..." |
|
Сообщ.
#2890
,
|
|
|
|
Цитата Romkin @ 1. Метакласс и метапрограммирование: тип объекта тоже объект. Согласен. В чистом С++ это есть на уровне шаблонов и только на время компиляции. В рантайм это не вынести, поскольку противоречит принципу "что не использую, за то не плачу". Цитата 2. RTTI: полная информация об объекте, объем которой контролируется программистом. С возможностью обмена этой информацией отдельно от собственно объекта. Согласен. Но не допустимо на уровне чистого С++, ибо также противоречит вышеуказанному принципу и ограничивает сферы применения языка. Может быть реализовано на уровне среды разработки и конкретного компилятора. Цитата 3. Прямая поддержка типа "метод объекта": методы как поля данных. Нам не нужно извращаться, чтобы написать ![]() ![]() if assigned(FOnClick) then FOnClick(Self); Объясни, зачем это нужно, кроме как затыкания дырок в дизайне? В рамках метапрограммирования, во время компиляции - да. Выбираем стратегию поведения в зависимости от "вида" объекта/класса. А вот во время выполнения... Почему не завести интерфейс с нужным методом? Цитата 4. Разделение на структуры, классы и интерфейсы, с четким разделением функций и контролем на уровне языка. Когда класс - просто структура можно сказать, что интерфейс - абстрактный класс. Нет, дело не в "структуре". Множественное наследование(в том числе и классов, а не интерфейсов) - вполне етественно, а его запрет отражается на возможностях моделирования. Читай теорию ООП, того же Б.Мейера. Чистые интерфейсы(в том виде, в котором они есть в C#, Java, Delphi) нужны только для затыкания дыры запрета множественного наследования. Никакой другой полезной нагрузки они не несут. Цитата Никакого. И зачем программист это сделал?Какой смысл в передаче объекта с виртуальными методами по значению предка? Брр. Цитата 5. Наличие дженериков с контрактными объявлениями, то есть шаблонов с четким контролем контракта объекта. ![]() Концепты... Эх. Потребовать от параметра шаблона, чтобы он реализовывал интерфейс(абстрактный класс), как это сделано в C#, можно и в рамках существующего стандарта. Только это не красиво. |
|
Сообщ.
#2891
,
|
|
|
|
Цитата Flex Ferrum @ "It's a kind of magic..." Flex Ferrum, у них там как я понял, можно менять порядок конструирования объекта(ну и удаление)... Тоесть можно сделать так, чтобы сначало отработал конструктор производного класса, а уж потом базового, ну и с удалением также, сначало удалица базовый, а уж потом производный. Правда так и несмог никто ответить, что будет если в базовом классе есть данные, с которыми работает производный... Видимо AV, которое там довольно нередко можно выхватить... |
|
Сообщ.
#2892
,
|
|
|
|
Цитата Romkin @ объект - не стуктура с виртуальными методами, подчиняющаяся правилам для структура, но абстракция со своими уникальными свойствами. По поводу набора предков. Попробую объяснить. В С++ объект это фактически структура, при создании вызываются конструкторы всех предков, причем каждый конструктор фактически работает с объектом именно как с предком, с поведением и данными предка. Уже это однозначно указывает на факт набора предков. Не знаю, как в Delphi, но в C++ наследование, это (в первую очередь) реализация отношения "is a" ("является"). По этой причине экземпляр наследника является (одновременно!, о ужас), экземпляром предка. Странно? |
|
Сообщ.
#2893
,
|
|
|
|
Цитата Romkin @ Вот, собственно, я и говорю: Delphi нашло возможность отбросить старую реализацию класса, как неудобную и устаревшую. А С++ насадило примочек, чтобы обойти недостатки этой структуры. Ну да, в С++ гнилые, поганые классы, по сравнению с делфевскими... Ты вот только ответь на один вопрос, почему в Делфийских, классных, красивых классах, которым С++'ные в подметки не годятся, нужно уничтожать все в ручную ? |
|
Сообщ.
#2894
,
|
|
|
|
Цитата KILLER @ Для совместимости со старіми классами. Ну да, в С++ гнилые, поганые классы, по сравнению с делфевскими... Ты вот только ответь на один вопрос, почему в Делфийских, классных, красивых классах, которым С++'ные в подметки не годятся, нужно уничтожать все в ручную ? Вообще не понятно. Вот есть, допустим ещё 2 языка со смешанной системой типов. Ява и шарп. Но там такой шаг в принципе понятен. Ссылочные типы ввели из-за того, что по другому не возможно реализовать сборщик мусора. Объектные типы оставили, чтобы разгрузить сборщик мусора и добавить быстродействие. В делфи, как всегда, фичу ввели, но наполовину. Ссылочные типы есть. Сборщика мусора нет. |
|
Сообщ.
#2895
,
|
|
|
|
Да про сборщик мусора уже обсуждали... Вообще я за то, чтобы все было ссылками. Это упрощает язык, делает возможным сборку мусора, избавляет от многих проблем и т.д. и т.п.
Но плохо, когда в языке есть деление на обычные типы и "необычные". Проблему с производительностью для примитивных типов можно решить, объявив их иммутабельными и запретив наследовать от них - тогда можно будет хранить значения, а не ссылки, и язык при этом не пострадает. |