Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 480 481 [482] 483 484 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#7216
,
|
|
|
|
Цитата D_KEY @ Можно еще просто забить и "писать, как пишется", отлавливая(или пропуская) баги Но вряд ли у вас так принято ? У нас не принято, т.к. мы "живем в демократическом обществе" и сами отвечаем за корректную реализацию наследуемого класса. И никакие идеологические отделы КПСС и бдительное око ВЧК\КГБ нам своих ограничений\регламентов на все случаи жизни не навязывают и железных занавесов не создают ![]() Если ты наследуешься от "по(ту)стороннего" базового класса, разработчик которого решил скрыть от тебя всю реализацию в private, то ты по любому в нее не влезешь и будешь просто вынужден вызывать его конструктор as is. А если я сам разрабатываю иерархию классов и предусматриваю ее развитие в будущем, то почему какой-то дядя должен мне запрещать вносить изменения\коррективы в процесс конструирования - у нас демократия или как? Ну, допустим, ошибусь я где-то, и что? Ошибиться можно где угодно, не только в конструкторах\деструкторах. Взять тот же метод Clear (с которого тут сыр-бор разгорелся с новой силой), для него что, не важен порядок вызовов, прикажете его тоже включать в список special members со спец.поддержкой порядка вызова со стороны компилятора? Поэтому пользовательские конструкторы (за исключением первой ступени - NewInstance) рассматриваются в дельфи не как нечто "неприкосновенное и божественное" с предопределенными правилами вызова, а как обычные методы, порядок вызова которых определяется самим разработчиком класса. Поэтому и нет понятий отдельного "конструирования\создания" базовых классов, "входящих" в дочерние. Никто никуда не входит, просто дочерний класс получает по наследству поля и методы предка, включая один или несколько методов инициализации, условно называемых constructor - все это становится "собственностью" класса-потомка и он сам отвечает за правильный порядок своей собственной инициализации, включая унаследованные поля. "Демократия, панимаишь. За что боролись, на то и напоролись" ![]() Это просто другой подход, "другая философия", не хорошая и не плохая, а просто другая. Если она тебе не нравится - ради бога. Но пытаться упорно доказывать, что она в принципе неправильная, глючная и бажная, приплетая какие-то unreal проблемы - просто наивно, т.к. эта модель много лет "живет и процветает", и вся офигенная иерархия VCL на ней построена (собственно говоря, многие особенности этой модели как раз и "заточены" именно под использование в VCL) |
|
Сообщ.
#7217
,
|
|
|
|
Цитата leo @ У нас не принято, т.к. мы "живем в демократическом обществе" и сами отвечаем за корректную реализацию наследуемого класса. В таком случае ты лучше бы ответил вот на это Цитата В твоем же случае разработчик базового класса, вызывая в конструкторе перекрытые в потомке методы, фактически полагается на авось - он не знает наверняка, успел ли потомок привести объект в согласованное состояние(т.е. имеем ли мы право дергать методы, или объект еще конструируется), с другой стороны, разработчик потомка, перекрывая метод, так же вынужден или рассчитывать на то, что ему может прийти мусор(например, просто зануленная память) вместо объекта, или вызывать конструктор предка после того, как обеспечит свои инварианты(но в этом случае он не может в своем коде обращаться к унаследованным полям и методам в процессе конструирования), или смотреть в реализацию базового класса... Цитата Если ты наследуешься от "по(ту)стороннего" базового класса, разработчик которого решил скрыть от тебя всю реализацию в private, то ты по любому в нее не влезешь и будешь просто вынужден вызывать его конструктор as is. Но он ведь может вызывать из своего конструктора виртуальные методы и тебе придется в каждом перекрытом методе это учитывать... Цитата А если я сам разрабатываю иерархию классов и предусматриваю ее развитие в будущем, то почему какой-то дядя должен мне запрещать вносить изменения\коррективы в процесс конструирования - у нас демократия или как? Т.е. держать все это в голове - нормально? А если ты вернешься к коду через, хотя бы, полгода? Демократия != бардак и каша. Цитата Что?Взять тот же метод Clear (с которого тут сыр-бор разгорелся с новой силой), для него что, не важен порядок вызовов, прикажете его тоже включать в список special members со спец.поддержкой порядка вызова со стороны компилятора? Цитата Поэтому пользовательские конструкторы (за исключением первой ступени - NewInstance) рассматриваются в дельфи не как нечто "неприкосновенное и божественное" с предопределенными правилами вызова, а как обычные методы Методы несконструированного объекта? Сильно. Цитата Это просто другой подход, "другая философия", не хорошая и не плохая, а просто другая. Если она тебе не нравится - ради бога. Еще раз. Это все понятно. Но холивар же Цитата Где? Догнивает скорее уж т.к. эта модель много лет "живет и процветает" Цитата и вся офигенная иерархия VCL Добавлено leo Цитата PHP: a fractal of bad design Do not tell me that “good developers can write good code in any language”, or bad developers blah blah. That doesn’t mean anything. A good carpenter can drive in a nail with either a rock or a hammer, but how many carpenters do you see bashing stuff with rocks? Part of what makes a good developer is the ability to choose the tools that work best. |
|
Сообщ.
#7218
,
|
|
|
|
Цитата --Ins-- @ И да, ни ты, ни флекс, никто еще в этой теме так и не раскрыл понятия "правильная/неправильная или плохо/хорошо" На самом деле критерий достаточно просто: если в результате своей работы ты получаешь архитектуру, для каждой компоненты которой чётко прописаны требования, зоны ответственности, контракты, интерфейсы и т. п., и каждый компонент соблюдает взятые на себя обязательства - это хорошо. Когда этого нет - это плохо. В данном случае: когда контракт удаления объекта размыт (может так, а может не так, а может ещё вот так), и каждый разработчик реализует его как хочет - это плохо. Когда контракт удаления объекта чётко определён - это хорошо. Аналогично с конструированием и любыми другими процессами. Чем выше показатель error prone в том или ином варианте архитектуры - тем эта архитектура хуже. Из в этом деле локальное удобство далеко не всегда коррелирует с глобальной правильностью. |
|
Сообщ.
#7219
,
|
|
|
|
Цитата D_KEY @ Методы несконструированного объекта? Сильно. D_KEY, ты давно перешел на троллинг? Может мне нужно прислушаться к Астароту? Ну ладно, на этот раз отвечу... Во-первых, в с++ тоже внезапно можно вызывать методы несконструированного объекта и мы об этом говорили. Сильно? И в с++ это и вправду беда, т.к. там объекта на момент вызова нет, а в Delphi - на момент вызова Create объект уже есть, причем конечного класса (а не конструируемого в данный момент предка), просто инициализация может быть еше не завершена. Во-вторых, где написано что методы объекта нельзя использовать для конструирования? Нигде. В третьих, рассматривать отдельно инвариант несконструированного объекта если и нужно, то только на стадии отладки и то редко. Если ты думаешь что код Delphi пестрит if инициализировано then... ты ошибаешься. Если считаешь что код дельфи постоянно глючит и падает - тоже, это зависит исключительно от кривизны рук, как и везде.Цитата Flex Ferrum @ В данном случае: когда контракт удаления объекта размыт В данном случае он также регламентирован. Просто иначе |
|
Сообщ.
#7220
,
|
|
|
|
Цитата --Ins-- @ В данном случае он также регламентирован. Просто иначе Эммм... Я считаю так: если программисты приучают себя писать FreeAndNil вместо простого Free (применение которого может приводить к невнятным проблемам) - то тут что-то не так. Добавлено Цитата --Ins-- @ D_KEY, ты давно перешел на троллинг? Может мне нужно прислушаться к Астароту? Ну ладно, на этот раз отвечу... Во-первых, в с++ тоже внезапно можно вызывать методы несконструированного объекта и мы об этом говорили. Сильно? И в с++ это и вправду беда, т.к. там объекта на момент вызова нет, а в Delphi - на момент вызова Create объект уже есть, причем конечного класса (а не конструируемого в данный момент предка), просто инициализация может быть еше не завершена. Во-вторых, где написано что методы объекта нельзя использовать для конструирования? Нигде. В третьих, рассматривать отдельно инвариант несконструированного объекта если и нужно, то только на стадии отладки и то редко. Если ты думаешь что код Delphi пестрит if инициализировано then... ты ошибаешься. Если считаешь что код дельфи постоянно глючит и падает - тоже, это зависит исключительно от кривизны рук, как и везде. Ins, ведь Qraizer всё хорошо расписал (и ты это подтвердил). В Delphi мы имеем дело с типичным вухэтапным конструированием. В C++ это бы выглядело бы так: ![]() ![]() #include <iostream> class TObject { public: template<typename T> static T* NewInstance() { T* result = new T(); result->ConstructObject(); return result; } private: virtual void BeforeConstruction() {} virtual void Create() {} virtual void AfterConstruction() {} void ConstructObject() { BeforeConstruction(); Create(); AfterConstruction(); } }; class TMyObject : public TObject { public: private: void Create() { std::cout << "MyObject created" << std::endl; } }; int main() { TMyObject *obj = TObject::NewInstance<TMyObject>(); } В чём проблема то? Ну привыкли вы к двухфазному конструированию. Ну что же теперь, других вариантов что-ли не бывает? |
|
Сообщ.
#7221
,
|
|
|
|
Цитата Flex Ferrum @ то тут что-то не так. Я согласен. Что-то не так в программистах. Использовать повторно ссылку - это моветон |
|
Сообщ.
#7222
,
|
|
|
|
Цитата --Ins-- @ Я согласен. Что-то не так в программистах. Использовать повторно ссылку - это моветон Если в момент вызова функции не гарантируется того, что объект по ссылке жив - это, по твоему, не моветон? |
|
Сообщ.
#7223
,
|
|
|
|
Цитата Flex Ferrum @ Если в момент вызова функции не гарантируется того, что объект по ссылке жив - это, по твоему, не моветон? Брр. С чего бы это может быть не гарантировано? Только от кривизны рук. Если ты уничтожаешь объект, а потом оказывается что он где-то используется - нафиг ты его уничтожаешь? Так что вижу только одну причину - ты умышленно уничтожаешь объект и позже хочешь повторно пользоваться этой ссылкой |
|
Сообщ.
#7224
,
|
|
|
|
Цитата --Ins-- @ D_KEY, ты давно перешел на троллинг? Ты от меня честного ответа ждешь ?Цитата Во-первых, в с++ тоже внезапно можно вызывать методы несконструированного объекта и мы об этом говорили. Сильно? Но это будет на уровне того же класса Возможно, с новым стандартом эта практика уйдет, т.к. появились делегирующие конструкторы.Цитата на момент вызова Create объект уже есть ... просто инициализация может быть еше не завершена. Взаимоисключающие параграфы Объект есть только тогда, когда он обеспечил свои инварианты. |
|
Сообщ.
#7225
,
|
|
|
|
Flex Ferrum, в общем мне трудно тут с тобой спорить, я никогда не был адептов использования FreeAndNil, наверное, никогда и не использую (категорично, но все же) и не понимаю тех, кто использует. У адептов FreeAndNil возможно и вправду что-то не так, раз они иначе не могут.
Добавлено Цитата D_KEY @ Ты от меня честного ответа ждешь ? Ээ, да |
|
Сообщ.
#7226
,
|
|
|
|
Цитата --Ins-- @ Брр. С чего бы это может быть не гарантировано? С того, что могут быть позваны виртуальные функции в момент уничтожения. Ведь могут? Могут. Значит эти функции должны содержать явные проверки на то, что объект находится в полуживом состоянии. |
|
Сообщ.
#7227
,
|
|
|
|
Цитата D_KEY @ Но это будет на уровне того же класса Какая разница - объекта все равно еще нет, а методы уже вызываются Сильно да? Инвариант не обеспечен и тут дергается метод |
|
Сообщ.
#7228
,
|
|
|
|
Цитата --Ins-- @ Какая разница - объекта все равно еще нет, а методы уже вызываются Сильно да? Инвариант не обеспечен и тут дергается метод ![]() Смотри. Инвариант обеспечивает создатель класса в конструкторе. Если он для этого использует методы - это его личное дело. Это один уровень. В твоем случае уровней несколько и они могут находится далеко друг от друга по иерархии наследования. |
|
Сообщ.
#7229
,
|
|
|
|
Цитата D_KEY @ В твоем случае Инвариант обеспечивает тот, кто перекрывает виртуальный метод. И конструктор |
|
Сообщ.
#7230
,
|
|
|
|
Цитата --Ins-- @ Инвариант обеспечивает тот, кто перекрывает виртуальный метод. И конструктор Как ты можешь обеспечить инварианты реализации базового класса, если тебе даже знать о них не положено? |