Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 86 87 [88] 89 90 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#1306
,
|
|
|
|
AfterConstruction - костыль. Почему? Потому что в C++ разграничение областей ответственности делается на уровне базового класса, и все что предоставляет базовый класс наружу - позволяет его не испортить (правило Мейерса "Старайтесь проектировать интерфейс так, чтобы использовать его правильно было легко, а неправильно - трудно"). В Дельфях я же вынужден хвататься за голову при каждой возможности "испортить" интерфейс и пихать в AfterConstruction код чтоб хоть как-то защититься от ситуации, когда неконсистентный объект получается не то что при использовании неверно спроектированного класса - при его конструировании (sic!)
|
|
Сообщ.
#1307
,
|
|
|
|
Цитата MyNameIsIgor @ D_KEY, ну что ты ведёшься на эти разговоры про "плюсы без шаблонов"? А почему без шаблонов, а не без цикла for? Или int выпилим? Ну, детский сад же! Человеку было интересно, можно ли так без шаблонов, я просто пояснил, что нельзя и даже сказал почему(хотя может и можно, обдумывать не хочется ). Шаблонофобия у многих есть, да, что поделаешь? |
|
Сообщ.
#1308
,
|
|
|
|
Отрыл статейку из сайта Королевство Делфи, советую прочитать и делфистам и С++сникам. Там подробно описано как и где отрабатывают конструкторы/деструкторы, описана обработки исключений, и т.д. описаны плюсы, описаны минусы...
Оригинал - статья Ну и сразу же кидаю провокационную цитату, чтобы подлить маслеца в огонь Было описана работа с try/catch и конструкторами/деструкторами Цитата ... Привел я этот пример не для демонстрации возможностей блока try...catch, а для того чтобы показать как С++ сам делает безопасным процесс "конструирования" класса. В Делфи все это ложиться на хрупкие плЭчи программера. Кстати о Делфях, я там не нашел аналог функции С++ - uncaught_exception() - показывает статус стека исключений. Т.е. есть щас необработанное исключение, или говоря системным языком стек сейчас раскручивается нормально? Применение? Пожалуйста: ![]() ![]() Transaction::~Transaction() // деструктор класса "Транзакция" { if ( uncaught_exception() ) Rollback(); else Commit(); } Благодаря этой функции ваш деструктор знает - нормальное это "устранение" класса или не нормальное. По-моему, очень даже пользительно. Ну ладно, об исключениях, как и ООП можно говорить часами. Но надо знать меру. ... Добавлено --Ins--, И всетаки AfterConstruction/BeforeDestruction - это что нинаесть костыли, ссылок для чего они нужны в гугле уйма... Один только ты считаешь что на них все держится... В Идеале же, это просто костыли... Которые то и используются оочень редко... Ты вот сам как считаешь, для чего они введены? С какой целью? |
|
Сообщ.
#1309
,
|
|
|
|
Вот, кстати, когда читал Саттера, не понравилась его категоричность, мол, uncaught_exception() не применима. Я так думаю, что это, конечно, не для каждодневного использования, но бесполезной вещью её тоже не назовёшь...
|
|
Сообщ.
#1310
,
|
|
|
|
А вот и еще про делфи, и про AfterConstruction...
Ссылка Цитата Все объекты создаются посредством вызова конструктора. Собственно конструктор не обязан называться Create, просто это принятое название данного метода. Конструктор на самом деле является методом класса, и в процессе его работы вызываются следующие методы: NewInstance InitInstance Create AfterConstruction На самом деле вызов этих методов происходит достаточно интересно. В TObject конструктор не выполняет никакой деятельности, однако, как корневой класс иерархии он создается на уровне RTM. Что же происходит? После вызова конструктора RTM вызывает метод NewInstance, который выделяет область в памяти, согласуясь при этом со значением vmtInstanceSize, которое формируется при компиляции. В рамках вызова NewInstance выполняется вызов InitInstance, который заполняет поля метода значениями, обозначенными в модификаторах default, далее выполняется код, описанный в теле процедуры Create (или той, что заявлена в качестве конструктора), после чего управление передается в точку, определенную в точке vmtAfterConstruction, которая по умолчанию указывает на метод AfterConstruction. Все эти манипуляции позволяют максимально упростить процесс гибкого создания экземпляра класса в рамках объектной модели Delphi. Таким образом, при создании экземпляра класса (объекта) вы можете «поприсутствовать» на любой его фазе. Смысл процедуры AfterConstruction состоит в том, чтобы выявить момент окончания конструирования класса. Удобство его использования состоит в том, что он вызывается только при удачном выполнении конструктора, что, сами понимаете достаточно выгодно. На сегодняшний момент только TCustomForm и TCustomDataModule перегружают этот метод специально для того, чтобы выполнить специфичные для них функции, так что мешает нам сделать то же самое? Но это уже вопрос конструирования класса. Хм... Афигеть как выгодно Тока причем тут, гениальные проектные решения, которые приводили делфисты я не понимаю |
|
Сообщ.
#1311
,
|
|
|
|
Цитата MyNameIsIgor @ Вот, кстати, когда читал Саттера, не понравилась его категоричность, мол, uncaught_exception() не применима. Я так думаю, что это, конечно, не для каждодневного использования, но бесполезной вещью её тоже не назовёшь... Я ни разу не применял - повода не было. На мой взгляд, это костыль. Добавлено Цитата KILLER @ Отрыл статейку из сайта Королевство Делфи, советую прочитать и делфистам и С++сникам. Там подробно описано как и где отрабатывают конструкторы/деструкторы, описана обработки исключений, и т.д. описаны плюсы, описаны минусы... Оригинал - статья Во вступлении как-то не очень правильные вещи написаны о С++, шаблонах и ООП. Дальше читать пока времени нет... |
|
Сообщ.
#1312
,
|
|
|
|
Цитата D_KEY @ Во вступлении как-то не очень правильные вещи написаны о С++, шаблонах и ООП. Дальше читать пока времени нет... Ну там вступление, я не читал, там вроде история описывается, немного ниже, уже начинается, я как бы бегло прочел, вечером тоже надо будет более детальнее прочитать |
|
Сообщ.
#1313
,
|
|
|
|
Везет же Цитата D_KEY @ .NET спроектирован не очень удачно, но не сказать что плохо(Это мнение некоторых моих знакомых, перешедших на .NET Мне просто интересно, твоим знакомым есть хоть с чем сравнивать? Мне вот есть с чем На с++ таких фреймворков нет и быть не может Цитата Мяут-Настоящий @ AfterConstruction - костыль. Почему? Потому что в C++ разграничение областей ответственности делается на уровне базового класса, и все что предоставляет базовый класс наружу - позволяет его не испортить (правило Мейерса "Старайтесь проектировать интерфейс так, чтобы использовать его правильно было легко, а неправильно - трудно"). В Дельфях я же вынужден хвататься за голову при каждой возможности "испортить" интерфейс и пихать в AfterConstruction код чтоб хоть как-то защититься от ситуации, когда неконсистентный объект получается не то что при использовании неверно спроектированного класса - при его конструировании (sic!) Э, нет, все наоборот. Я как раз могу проектировать классы очень просто. Все что мне нужно сказать потомку - это не забывайте дергать метод SetModified когда хотите чтобы ваше изменение привело к сбросу флажка И все. Плохой контракт? Слишком сложный? Больше мне ни о чем с потомками договариваться не нужно, все остальное будет само работать ожидаемым образом. А вот у вас... Каждый из потомков должен самостоятельно заботиться о том, чтобы состояние Modified в различные моменты времени соответствовало задаче. Это в ваших системах черт ногу сломит, притом как в наших весь контракт между предком и потомком обычно описывается простой фразой "перекройте такой-то и такой-то метод и сделайте в нем что захотите" Поэтому и полно повторно используемых классов, компонентов и библиотек, так как проектирование их - это достаточно простая задача, и использование - тоже Учись, студент Добавлено Цитата D_KEY @ Во вступлении как-то не очень правильные вещи написаны о С++, шаблонах и ООП. Дальше читать пока времени нет... Да Дмитрий Логинов - это как бы и не особо авторитет |
|
Сообщ.
#1314
,
|
|
|
|
Цитата --Ins-- @ Каждый из потомков должен самостоятельно заботиться о том, чтобы состояние Modified в различные моменты времени соответствовало задаче. Нет. У нас потомок вообще должен знать о Modified не более чем сказано в интерфейсе базового класса. Ну и как я уже говорил - использовать геттеры-сеттеры в конструкторе - некомильфо. |
|
Сообщ.
#1315
,
|
|
|
|
Цитата --Ins-- @ А вот у вас... Каждый из потомков должен самостоятельно заботиться о том, чтобы состояние Modified в различные моменты времени соответствовало задаче. Это ты сам взял заведомо костыльную задачу, и попытался в точности с делфи перевести ее на С++, тебе уже 200 раз было сказано, что занафиг тот Modified менять в конструкторе класса? Ты тупо предложил половину функционала - перенести на плечи конструктора, тоесть по сути, если у тебя произойдет исключение при создании документа, то это кошмар будет при твоем подходе... Добавлено --Ins--, почему я не могу сделать так? А если и могу чем вот это хуже твоего AfterConstruction ?? Конечно, это примитивный пример, просто показать, как можно еще сделать, и ничего не нарушая... ![]() ![]() class CAbstractDocument { public: virtual CAbstractDocument* CreateClearDocument() = 0; virtual bool IsModified() const = 0; virtual bool DoSave() = 0; virtual void Close() = 0; virtual void Modify(bool bIsModify) = 0; virtual void ProcessMessages() = 0; virtual std::string GetUserText() const = 0; }; class CDocument: public CAbstractDocument { public: CDocument() : m_bIsModified(false), szText("") { std::cout << "Create instance of document" << std::endl; } virtual bool IsModified() const { return m_bIsModified; } virtual CAbstractDocument* CreateClearDocument() { std::cout << "cleared document is created" << std::endl; return this; } virtual bool DoSave() { if( m_bIsModified ) { std::cout << "Saving current document..." << std::endl; } return true; } void Close() { std::cout << "Document is closed" << std::endl; } virtual void Modify(bool bIsModify) { m_bIsModified = bIsModify; } void ProcessMessages() { std::cout << "Document is opened..." << std::endl; for(;;) { std::string szNewLine; std::cin >> szNewLine; if(szNewLine == "exit") { if( DoSave() ) { Close(); } break; } Modify(true); szText.append(szNewLine); } } std::string GetUserText() const { return szText; } private: bool m_bIsModified; std::string szText; }; int main(int argc, _TCHAR* argv[]) { CAbstractDocument* pDocument = new CDocument(); pDocument->CreateClearDocument(); pDocument->ProcessMessages(); std::cout << pDocument->GetUserText(); delete pDocument; return 0; } ![]() ![]() Create instance of document cleared document is created Document is opened... line1 line2 line3 exit Saving current document... Document is closed line1line2line3 Добавлено Туже реализацию CDocument, можн овообще скрыть нафиг, чтобы юзеру тупо был в пользование один интерфейс CAbstractDocument, Заодно можно ему задать какие виды документов вообще можно юзать, и ему останется только вызвать нужные методы и все, ни о чем вообще не задумываясь, да и поломать тут практически нечего, а для расширения, наследуйся хоть от CAbstractDocument, и реализуй который тебе нужно или от CDocument, и реализуй уже на основе написаного, какие проблемы? |
|
Сообщ.
#1316
,
|
|
|
|
Цитата --Ins-- @ Про qt ты наверное ничего не слышал. На с++ таких фреймворков нет и быть не может |
|
Сообщ.
#1317
,
|
|
|
|
Цитата --Ins-- @ Цитата D_KEY @ .NET спроектирован не очень удачно, но не сказать что плохо(Это мнение некоторых моих знакомых, перешедших на .NET Мне просто интересно, твоим знакомым есть хоть с чем сравнивать? Мне вот есть с чем ![]() С явой и С++. Цитата На с++ таких фреймворков нет и быть не может То есть под .NET нельзя писать на С++? А Qt чем-то хуже? А стандартному С++ такие фреймворки только помешают. Цитата Так о чем это отличается от тех вариантов, что тебе давали на С++?Все что мне нужно сказать потомку - это не забывайте дергать метод SetModified когда хотите чтобы ваше изменение привело к сбросу флажка И все.Цитата Скорее глупый, ИМХО. Но тут можно долго без толку копья ломать.Плохой контракт? Слишком сложный? Цитата А вот у вас... Каждый из потомков должен самостоятельно заботиться о том, чтобы состояние Modified в различные моменты времени соответствовало задаче. Точно также, как у вас - вызываем SetModifiedЦитата Поэтому и полно повторно используемых классов, компонентов и библиотек, так как проектирование их - это достаточно простая задача, и использование - тоже Учись, студент Именно поэтому библиотеки пишутся, в основном, на С и С++? Кстати, если библиотека не кроссплатформенная она меня вряд ли заинтересует. Цитата А кто это? Цитата D_KEY @ Во вступлении как-то не очень правильные вещи написаны о С++, шаблонах и ООП. Дальше читать пока времени нет... Да Дмитрий Логинов - это как бы и не особо авторитет ![]() |
|
Сообщ.
#1318
,
|
|
|
|
Кстати, о принципе наименьшего удивления...
в Delphi ![]() ![]() var a, d, e: Extended; b, c: Integer; begin a := 20; b := 10; c := 50; d := 10; e := a + (b / c) * d; // e = 22; end; в c# ![]() ![]() { float a = 20, d = 10; int b = 10, c = 50; float e = a + (b / c) * d; // e = 20; } |
|
Сообщ.
#1319
,
|
|
|
|
python
![]() ![]() >>> a = 20.; d = 10. >>> b = 10; c = 50 >>> e = a + (b / c) * d >>> print e 20.0 Выкидывай свое Delphi |
|
Сообщ.
#1320
,
|
|
|
|
Мяут-Настоящий, купи калькулятор
|