sender as

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: sender as

Сообщение Лекс Айрин » 10.02.2016 15:09:47

zub, учтите, что виртуальность метода... виртуальна. На самом деле, каждому виртуальному методу соответствует 1(один) реальный метод. Который, если надо, вызывает очередь порожденных методов из объектов предков.

Проверка соответствия реально вызываемого метода начинается от текущего компилируемого файла. Соответственно, если метод/объект/класс не определен до конца, то тогда используются определения из родительского объекта/класса.
Собственно, заполнение таблицы виртуальных методов это одна из задач... могу, кстати, ошибаться... синтаксического анализатора.
Сложность, кстати, не особо добавляет то, что используемые модули до этого предварительно должны быть откомпилированы.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: sender as

Сообщение zub » 10.02.2016 16:06:01

Лекс Айрин
учтите, что виртуальность метода... виртуальна. На самом деле, каждому виртуальному методу соответствует 1(один) реальный метод. Который, если надо, вызывает очередь порожденных методов из объектов предков.

Проверка соответствия реально вызываемого метода начинается от текущего компилируемого файла

Не лейте воду. чудеса не в том что мы "чудесным" образом переопределили
Код: Выделить всё
TEdit = class (MyEditUnit.TMyEdit);

а в том что внутри TCustomForm.ProcessResource или гдето ниже при прочтении из lfm которая стала ресурсом строчки вида
Код: Выделить всё
object Edit1: TEdit

был вызван конструктор именно нашего TEdit, а не штатного

Ткните меня носом где это происходит. Рассуждать про виртуальную виртуальность можно долго, особенно не понимая что это такое
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: sender as

Сообщение Лекс Айрин » 10.02.2016 16:59:50

zub писал(а):Ткните меня носом где это происходит.


именно там это и происходит. Весь остальной механизм обеспечивается компилятором.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: sender as

Сообщение stanilar » 10.02.2016 17:48:50

zub писал(а): был вызван конструктор именно нашего TEdit, а не штатного

А конструктор нашего TEdit нигде не был перекрыть, почему он должен отличаться от штатного?
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: sender as

Сообщение zub » 10.02.2016 18:10:07

Лекс Айрин
>>Весь остальной механизм обеспечивается компилятором.
естественно, чедес не бывает. только это не объяснение - на компилятор всё "списать" можно, любой баг\фичу.

чуток раскопал:
всё дело в
Код: Выделить всё
function TReader.FindComponentClass(const AClassName: String): TComponentClass;

из rtl\objpas\classes\reader.inc
первым делом описание разискиваемого класса ищется в таблице vFieldTable из vmt класса формы, а в нем естественно наша подмена.

Раньше я думал что поиск осуществляется по списку зарегистрированных компонентов... а тут вон оно как))

Всеравно ИМХО данный способ это хак и советовать его использовать нестоит. только если побаловаться

stanilar
>>А конструктор нашего TEdit нигде не был перекрыть, почему он должен отличаться от штатного?
потому что это другой класс и соответственно другая vmt. Даже если сам код конструктора не отличается, ему скрытым параметром передается указатель на вмт конструируемого экземпляра.
т.е. вызов штатного
tedit.create
и переопределенного
tedit.create
это разные случаи, даже без перекрытия
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: sender as

Сообщение Kemet » 10.02.2016 19:30:17

stanilar писал(а):Может написать класс-хелпер для TEdit?
Хелперы - ЗЛО. Их наличие говорит о том, что программист не использовал мозг при разработке проекта.
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: sender as

Сообщение Лекс Айрин » 10.02.2016 20:13:54

zub писал(а):Всеравно ИМХО данный способ это хак и советовать его использовать нестоит. только если побаловаться


Это не хак... это часть внутренней реализации ООП.

Добавлено спустя 3 минуты 17 секунд:
А вот как раз хелпер это и есть грязный хак.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: sender as

Сообщение stanilar » 10.02.2016 20:18:21

Kemet писал(а):Хелперы - ЗЛО.

Абсолютно согласен. Их наличие говорит о том, что программист класса, к которому пишется хелпер, не просто не использовал мозг, но так и не научился правильно задавать public/private/protect. IMHO для правильного спроектированного класса, не может возникнуть потребности в написании хелпера.

zub писал(а):Всеравно ИМХО данный способ это хак и советовать его использовать нестоит.

ИМХО Вполне себе достойный метод, отвечающий структуре языка и принципам ООП. Его стоит в обязательном порядке советовать новичкам:
1) Заставляет задуматься о том, что такое ООП.
2) Этот прием позволяет делать быстрый и удобный рефакторинг кода, для вынесения TMyEdit в собственный компонент, что в данной задаче является наиболее правильным решением, с точки зрения проектирования.
3) Дает навык удобной и быстрой разработки собственных компонент. Создание TMyEdit в виде компонента, на этапе разработки, не всегда является правильным решением, от которого в дальнейшем, возможно, придется отказаться. Для экономии времени и возможности оценить требуемую функциональность "на лету", такой прием вполне подходит.

З.Ы. Задача разработки собственной компоненты "под текущие нужды", не очень удобна из-за раздельной компиляции bpl и самого проекта, что потенциально несет в себе еще большие проблемы, чем одновременная компиляция кода будущей компоненты и проекта.

Добавлено спустя 16 минут 20 секунд:
zub писал(а):другая vmt.

насколько помню, vmt может содержать ссылку на другую vmt, и именно ссылку на vmt класса TEdit содержит класс TMyEdit ( конкретно, в поле vmtParent). Так что в данном коде конструктор одинаков для обоих классов.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: sender as

Сообщение zub » 10.02.2016 20:43:27

Лекс Айрин
>>Это не хак... это часть внутренней реализации ООП.
К ооп это не имеет никакого отношения. Это особенность внутренней структуры классов + особенность процедуры создания наформошлепаных форм из ресурсов.
Если есть какойнить документ в котором регламентирован такой порядок поиска описяния класса - да, не хак. Если нет - гарантий что в следующей версии fpc rtl\objpas\classes\reader.inc будет работать подругому нет никаких

stanilar
>>ИМХО Вполне себе достойный метод, отвечающий структуре языка и принципам ООП. Его стоит в обязательном порядке советовать новичкам:
Новичкам гораздо полезней будет посоветовать попробовать отказаться от дизайнера - проку будет больше чем от такого "переопределения".
>>1) Заставляет задуматься о том, что такое ООП.
в чем связь та с ООП?)) с RTTI вижу, с ООП нет
>>2,3
Очень сомнительно. Паскаль строгий язык, и то что он позволяет себе вольности не должно быть призывом к использованию таких вольностей

>>насколько помню, vmt может содержать ссылку на другую vmt
Может, и содержит на вмт родителя, но это для другого. Экземпляр класса имеет ссылку на свою вмт, а наш переопределенный tedit имеет вмт отличную от штатного тедита
>>Так что в данном коде конструктор одинаков для обоих классов.
продизасемблируйте и посмотрите разницу. Как вы себе представляете что 2 одинаковых вызова с одинаковыми параметрами будут создавать в разных случаях 2 разных класса?
Магия компилятора? ага))

Kemet
>>Хелперы - ЗЛО. Их наличие говорит о том, что программист не использовал мозг при разработке проекта.
Если их пихать везде где ненадо - да, зло. А по уму - вполне годится.
Это позволяет добавить новый "синтаксически подсахореный" функционал к чужим исходникам не правя их.
Обычно какраз наоборот, автор сделал всё с умом, а следующий програмист подгоняет всё под свои извращенные нужды))
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: sender as

Сообщение stanilar » 10.02.2016 21:27:14

zub писал(а):Новичкам гораздо полезней будет посоветовать попробовать отказаться от дизайнера

Визуального? Предлагаете писать крайне второстепенный код задания параметров визуальных контролов прямо в коде? Нет, это не полезней. Даже наоборот - может приучить путать UI-логику с бизнес-логикой.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: sender as

Сообщение zub » 10.02.2016 21:48:51

Нет, предлагаю разобраться как это всё работает и не путать ртти, ооп и sender as
>>Предлагаете писать крайне второстепенный код задания параметров визуальных контролов прямо в коде?
Новичкам да, чтоб отсутствие дизайнера и инспектора не вызывало ступор, что плохого когда человек знает как оно устроено?
В нормальных программах принято запоминать размеры\положения окон\в некоторых даже перекомпоновывать чтото(docking) такчто по уму то что осталось после дизайнера всеравно придется поправить))

>>Даже наоборот - может приучить путать UI-логику с бизнес-логикой.
обычно как раз наоборот - дизайнер приучает писать всю логики в onЧетоТам, плодить кучу "осмысленных" EditNN...
Да в дизайнере просто нашлепать нцать едитов и лабелов, А без дизайнера нормальный человек гораздо быстрее задумается как этот процесс автоматизировать и минимизировать, в итоге код будет компактней и проще
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: sender as

Сообщение stanilar » 10.02.2016 23:08:29

zub писал(а):как оно устроено

Для этого надо уметь пользоваться MSDN и уметь программировать на чистом WinAPI. Это не только довольно сложно, но и не очень нужно. Особенно в свете многоплатформенности.

zub писал(а):запоминать размерыположения оконв некоторых даже перекомпоновывать

Разве для этого нет компонент? В одном из моих последних проектов напарник просто что-то кинул на форму, и все вышеперечисленное стало доступно.

zub писал(а):дизайнер приучает писать всю логики в onЧетоТам, плодить кучу "осмысленных" EditNN...

А без дизайнера будет иначе? А между прочим дельфевый код, что написан в onЧетоТам более соотвествует принципам ООП, чем изредка наблюдаемый код той-же явы, в которой, как мне известно, и принято размыливать бизнес-код UI-логикой( по крайней мере именно встречаемые мною явисты испытывают странную любовь к созданию UI в процедурах, а не визуально ). Чтоб понять это, достаточно обявить свой TForm=class(TMyForm) и TEdit=class(TMyEdit), где TMyForm и TMyEdit вовсе не наследники вкл, и проект на onЧетоТам и кучи EditNN станет из визуального, скажем консольным. А может превратится в службу винды. И все эти превращения - без переписывания кода, что есть не только тру ООП, но и большой гуд проекту с точки зрения надежности.

zub писал(а):в итоге код будет компактней

Как бизнес код, смешанный в кодом работы визуальных элементов, может стать компактнее?

Добавлено спустя 13 минут 12 секунд:
zub писал(а):Магия компилятора?

Никакой магии, вызовы то происходят из разных контекстов. В данном случае разность контекстов будет определяться выдимостью типов.

zub писал(а):Экземпляр класса имеет ссылку на свою вмт, а наш переопределенный tedit имеет вмт отличную от штатного тедита

В экземпляре класса нследника есть ссылка на родительскую вмт. И наш переопределенный tedit содержит ссылку на вмт штатного тедита. И тут не нужен дизассембер, если это не так, то всякие приемы мира ООП, типа TEdit(TMyEdit), потеряют силу, и наши заклинания будут лишь бессильно искажать картинку монитора, не в силах закастовать класс.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: sender as

Сообщение zub » 11.02.2016 00:06:11

Для этого надо уметь пользоваться MSDN и уметь программировать на чистом WinAPI. Это не только довольно сложно, но и не очень нужно. Особенно в свете многоплатформенности.

Я не говорю про откат на winapi. Просто сделать lcl приложение с рантайм созданием форм и их содержимым. Xотя конечно понимать что всё это "обертка" и в конечном итоге работает winapi|qt|gtk тоже не помешает))

Разве для этого нет компонент? В одном из моих последних проектов напарник просто что-то кинул на форму, и все вышеперечисленное стало доступно.

что-то кинул на форму, и все вышеперечисленное стало доступно.

Вот про это я и говорю - чтото... гдето...

А между прочим дельфевый код, что написан в onЧетоТам более соотвествует принципам ООП, чем изредка наблюдаемый код той-же явы, в которой, как мне известно, и принято размыливать бизнес-код UI-логикой

Раз уж вы так ратуете за разделение - в onЧетоТам быть ничего не должно кроме вызова mySuperBusinessUnit.mySuperBusinessProc(...) или еще лучше юзать то, что для этого предназначено в LCL|VCL - TActions.
Тогда можно поговорить о разделении, а извиняюсь загрузка чего бы то ни было спрятаная в TmyForm.OnLoadButtonClick - это каша а не разделение

Чтоб понять это, достаточно обявить свой TForm=class(TMyForm) и TEdit=class(TMyEdit), где TMyForm и TMyEdit вовсе не наследники вкл, и проект на onЧетоТам и кучи EditNN станет из визуального, скажем консольным.

Уже пробовали?)) гораздо логичней как я написал в предидущем цитировании

И все эти превращения - без переписывания кода, что есть не только тру ООП, но и большой гуд проекту с точки зрения надежности.

С описаным вами подходом это мягко сказать - неправда, и даже если в итоге ценой ненужных копипастений вы получите рабочее консольное приложение - это будет хрень. TForm это гуй, она предпологает организацию и способы работы свойственные гую, тянет за собой кучу нигде не нужных кроме гуя зависимостей... и т.д. и т.п. А самое главное, сама по себе НИКАК НЕ ОБЕСПЕЧИВАЕТ РАЗДЕЛЕНИЕ "UI-логики с бизнес-логикой"

Как бизнес код, смешанный в кодом работы визуальных элементов, может стать компактнее?

Кто заставляет его мешать? создать чтото в рантайме значит смешать?
Создаем в дизайнере нцать TEdit`ов, каждый тыкаем мышкой и настраиваем в инспекторе как надо, недай бог потом придется перенастроить... рутина? Думаем как это можно оптимизировать - а никак, кроме как запилить в лазаре работу с множественным выбором компонентов в инспекторе...
Создаем в рантайме нцать TEdit`ов, каждый кодом настраиваем как надо... рутина? Думаем как это можно оптимизировать - да хоть как, например пиши универсальную процедуру создания однотипных компонентов
Я про вот это говорю.
Щас вы конечно скажете что формы сложные, не унифицируются... потому и сложные что сделаны в дизайнере

Добавлено спустя 19 минут 34 секунды:
Никакой магии, вызовы то происходят из разных контекстов. В данном случае разность контекстов будет определяться выдимостью типов.

никакой, TReader.FindComponentClass имеет ссылку на созаваемую форму, в список пропертей которой попал наш подмененный tedit, оттуда берутся и адрес конструктора и указатель на vmt подмененного tedit и осуществляется вызов нужного нам конструктора с нужным нам скрытым параметром в виде его вмт.
Что вы подразумеваете под разницей контекстов? rtl\objpas\classes\reader.inc давно скомпилирован вместе с fpc и ничего о новом классе незнает
вы хотите сказать что вызовы TEdit.Create и TмуEdit.Create абсолютно одинаковы и по адресу и по параметрам? нет, это не так

В экземпляре класса нследника есть ссылка на родительскую вмт.

Есть, только она нужна для работы inherited, is, возможно as и подобного. В данном случае это не имеет значения
Последний раз редактировалось zub 11.02.2016 00:38:04, всего редактировалось 1 раз.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: sender as

Сообщение stanilar » 11.02.2016 00:37:21

zub писал(а):Уже пробовали?))гораздо логичней как я написал в предидущем цитировании

Почти всегда так делаю. Просто названия событиям нужно давать поразумнее, а не TButton1Click.

zub писал(а):Тогда можно поговорить о разделении, а извиняюс загрузка чегопыто нибыло спрятаная в TmyForm.OnLoadButtonClick - это каша

Ну будет она спрятана в mySuperBusinessUnit.OnLoad_NOT_ButtonClick, какая разница? Думаете, от этого бизнес код перестанет быть связанным с UI?

zub писал(а):С описаным вами подходом это мягко сказать - неправда, и даже если в итоге ценой ненужных копипастений вы получите рабочее консольное приложение - это будет хрень

Никаких копипастей. А вот в случае выделении логики в отдельный mySuperBusinessUnit нагрузка на программиста возрастет в два раза: придется писать отдельно как консольное, так и визуальное приложение.

zub писал(а):А самое главное, сама по себе НИКАК НЕ ОБЕСПЕЧИВАЕТ РАЗДЕЛЕНИЕ "UI-логики с бизнес-логикой"

Ну как же не обеспечивает? Где Вы увидите в форме код инициализации вин-контролов, где код назначения им событий? Де факто, форма - это уже готовая среда для удобной и быстрой разработки бизнес логики, которую очень легко отвязать от визуальной составляющей описанным мною способом.

Добавлено спустя 8 минут 13 секунд:
zub писал(а):В данном случае это не имеет значения

Имеет, реадер то будет читать не TMyEdit, a TEdit. Можете добавить к TMyEdit published свойство, и посмотреть как обломится рантайм.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: sender as

Сообщение zub » 11.02.2016 01:01:08

Почти всегда так делаю. Просто названия событиям нужно давать поразумнее, а не TButton1Click.

а всякие MyTform.OnResize .onShow и иже с тем что собственно в консоли нафиг ненадо куда деваете?
Ну будет она спрятана в mySuperBusinessUnit.OnLoad_NOT_ButtonClick, какая разница? Думаете, от этого бизнес код перестанет быть связанным с UI?

Естественно, только не в mySuperBusinessUnit.OnLoad_NOT_ButtonClick, а именно в mySuperBusinessUnit.SuperBusinessProc. Если при этом mySuperBusinessUnit ничего не будет знать о TmyForm (т.е. форма и всё что связано с гуем не будет фигурировать в обоих uses`ах mySuperBusinessUnit) можно будет говорить о полном разделении. Такой подход позволит организовать логику как надо логике, а не с оглядкой на событийную модель работы гуя.
Полное разделение - т.е. логику можно например выделить в отдельную длл
Никаких копипастей. А вот в случае выделении логики в отдельный mySuperBusinessUnit нагрузка на программиста возрастет в два раза: придется писать отдельно как консольное, так и визуальное приложение.

Я уже сказал про onResize и прочую подобную пакость, которая бизнес логике ненужна... такчто покопипастить придется. Писать 2 обертки над логикой консольную и гуйную как никрути - тоже придется, и это правильно, нужно только постараться чтобы они были минимальными.
Ну как же не обеспечивает? Где Вы увидите в форме код инициализации вин-контролов, где код назначения им событий? Де факто, форма - это уже готовая среда для удобной и быстрой разработки бизнес логики, которую очень легко отвязать от визуальной составляющей описанным мною способом.

Вот как то так, совсем никак не обеспечивает.
Мне на форме хватит объявления нцати tedit`ов которые в консоли ненужны. Кстати как вы с контролами поступаете? утягиваете в консоль? Но если в консоли они не будут проинициализированы, то и tedit.text запросить нельзя...

Имеет, реадер то будет читать не TMyEdit, a TEdit. Можете добавить к TMyEdit published свойство, и посмотреть как обломится рантайм.

Не понял, подробнее что и где обломится?
Последний раз редактировалось zub 11.02.2016 01:06:02, всего редактировалось 5 раз(а).
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 238

Рейтинг@Mail.ru