Страница 1 из 1
Как выглядит class (схема)
Добавлено: 29.03.2015 19:14:26
MandelLamoureux
Всем привет. Мне было очень интересно узнать как устроены классы, и однажды вечером я решил нарисовать схему.
На схеме изображено как далеко можно зайти следуя по ссылкам в только что созданном экземпляре класса (class, а не object), какой и сколько RTTI информации существует о классе его методах и свойствах.
Это всего лишь моё небольшое исследование, которое я провёл исключительно из интереса.
Для примера я взял класс с довольно простой иерархией, TUnicorn <- TPony <- TObject
Код можно посмотреть здесь, его совсем немного:
http://pastebin.com/rTKkuT0UПеред тем как показать схему:
1) Адреса заменил на константы вида $(YYY_ADDR_ZZ), в принципе на них обращать внимания не стоит, все указатели отметил стрелками (там где адреса должны совпадать, они совпадают).
2) Если структура пуста, она изображена без полей, для экономии места, например: TInterfaceTable пуста, т.к. в классах не реализован ни один интерфейс.
3) Во всей этой схеме есть 1 поле - назначение которого для меня загадка, ClassTable (отмечен фиолетовым) если Вы про него что-то знаете, дайте мне знать.
4) Структура TPropList сама по себе не существует, её в рантайме создал я, для получения списка свойств (но информация о самих свойствах, на которую есть указатели в этой таблице - существует всегда).
Собственно сама схема, трижды всё перепроверил, но ошибки не исключены:
https://www.dropbox.com/sh/luewmnj8fi0d ... NtjZa?dl=0Если обнаружили ошибки или неточности, дайте мне знать!
upd0: вернул картинку.
Re: Как выглядит class (схема)
Добавлено: 02.05.2017 10:37:56
wavebvg
Жалко картинка не сохранилась

Re: Как выглядит class (схема)
Добавлено: 02.05.2017 12:08:19
Лекс Айрин
неточность в названиях классов.. получается, что единорог это всегда маленькая лошадь?
MandelLamoureux писал(а):ClassTable
Собственно, название говорит за себя...
Скорее всего, это таблица (порожденных и/или порождаемых) классов. Или ссылка на элемент в оной. Но подробнее можно было бы узнать если увидеть картинку.
Добавлено спустя 12 минут 26 секунд:Если порыться в исходниках, то этот метод определен так
Код: Выделить всё
class function TObject.ClassType : TClass;
begin
ClassType:=TClass(Pointer(Self))
end;
Если я правильно понимаю, то это указатель на структуру класса.
Re: Как выглядит class (схема)
Добавлено: 03.05.2017 12:03:32
wavebvg
Да, Вы правильно понимаете.
На самом деле все можно узнать либо аналитически, либо почитав тематические блоги и т.п. Но на это потребуются усилия и серьезные исследования. Вот эта картинка мне показалась отражающей все необходимые аспекты для быстрого ознакомления, а где я её сохранил - найти теперь не могу.
Зачем это нужно? Ну, в новых Дельфях не особо и нужно - там есть готовые решения, а в реальном мире:
* добавить данные в VMT класса (опять же RunTime), чтобы все объекты этого класса (но не их наследники) имели доступ к этим данным (вполне возможно сделать, используя какие-либо неиспользуемые части VMT, к примеру AutoTable)
* добавить хук на изменения свойства в RunTime (всё просто, пока не столкнетесь с переопределением статического метода, который не удается найти в структуре класса)
Возможно я что-то не знаю и есть уже решения для FPC/OldDelphi (в JEDI есть, но их приходится дописывать и обновлять, потому что все как надо не работает или нет возможности работать с DynArray через RTTI)
Re: Как выглядит class (схема)
Добавлено: 03.05.2017 12:26:13
Лекс Айрин
wavebvg писал(а):потому что все как надо не работает или нет возможности работать с DynArray через RTTI)
Я бы не назвал это недостатком.
wavebvg писал(а):всё просто, пока не столкнетесь с переопределением статического метода, который не удается найти в структуре класса
А смысл? Если это требуется то, в большинстве случаев, что-то сделано не так. Использование подобных хаков может легко поломать программу.
wavebvg писал(а): или нет возможности работать с DynArray через RTTI
Вполне логично... это ведь внутренняя кухня , к которой доступ как бы должен отсутствовать.
Re: Как выглядит class (схема)
Добавлено: 03.05.2017 13:29:05
wavebvg
Лекс Айрин писал(а):А смысл? Если это требуется то, в большинстве случаев, что-то сделано не так. Использование подобных хаков может легко поломать программу.
К примеру, чтобы отделить реализацию от структуры.
1. Берем обычный блоатваре датасет
2. Берем объект (к примеру Item коллекции, да и саму коллекцию тоже)
3. Пишем код-эмуляцию аннотации - сопоставления полей
4. Загрузка/сохранение коллекции становится куда проще, появляется возможность загружать составные структуры и т.п. без необходимости рулить DataSet-ом с его FieldByName на каждый **** или созданием статических полей и привязки логики к внутренностям DM
Лекс Айрин писал(а):Вполне логично... это ведь внутренняя кухня , к которой доступ как бы должен отсутствовать.
С такой логикой весь RTTI - внутренняя логика и не стоит им пользоваться
Re: Как выглядит class (схема)
Добавлено: 03.05.2017 13:40:58
Лекс Айрин
wavebvg писал(а):4. Загрузка/сохранение коллекции становится куда проще, появляется возможность загружать составные структуры и т.п. без необходимости рулить DataSet-ом с его FieldByName на каждый **** или созданием статических полей и привязки логики к внутренностям DM
Я бы использовал либо ссылку на сырые (или не очень) данные, либо дженерики.
wavebvg писал(а):С такой логикой весь RTTI - внутренняя логика и не стоит им пользоваться
Конечно. Но это не вина создателей библиотеки, так что приходится пользоваться.
Re: Как выглядит class (схема)
Добавлено: 03.05.2017 14:30:18
serbod
MandelLamoureux писал(а):Если обнаружили ошибки или неточности, дайте мне знать!
Twilight Sparkle уже давно не TUnicorn, а TPonyPrincess(TPony, IUnicorn, IPegasus). И вообще, тема интерфейсов не раскрыта.
wavebvg писал(а):Берем обычный блоатваре датасет, пишем код-эмуляцию аннотации - сопоставления полей
TDataSet это базовый класс с произвольным набором полей, изменяемых в runtime. Он может быть виртуальным, то есть не содержать данные, а служить оберткой для доступа к данным. А для вашего случая существуют published property, которые автоматом попадают в RTTI и доступны как в IDE, так и по именам в runtime.
Во внутреннюю структуру объектов действительно лучше не лезть, она может отличаться на разных платформах, архитектурах и версиях компилятора. Наружу торчит вполне достаточно protected и public свойств. Еще часть возможностей доступно через функции и глобальные переменные модуля System.
Re: Как выглядит class (схема)
Добавлено: 27.05.2017 21:22:22
MandelLamoureux
Первый ответ в теме чуть более чем через 2 года.

А картинку я вернул.

Re: Как выглядит class (схема)
Добавлено: 27.05.2017 22:07:19
zub
>>3) Во всей этой схеме есть 1 поле - назначение которого для меня загадка, ClassTable (отмечен фиолетовым) если Вы про него что-то знаете, дайте мне знать.
Подобные вещи я ковырял когдато очень давно, поэтому - емнип это таблица типов публишед полей, тип поля берется из нее по смещению ClassTypeIndex из своего описания.
Re: Как выглядит class (схема)
Добавлено: 27.05.2017 23:55:39
MandelLamoureux
Спасибо, не догадался проверить это раньше, в данный момент времени нет, не знаю есть ли смысл переделывать схему.

Re: Как выглядит class (схема)
Добавлено: 29.05.2017 10:21:50
Лекс Айрин
MandelLamoureux, конечно. Для лучшего понимания процесса использования классов.
Re: Как выглядит class (схема)
Добавлено: 29.05.2017 19:51:02
zub
С содержимым картинки при обычном "процессе использования" никогда не столкнешся. ИМХО гораздо полезней чем глядеть на такие картинки - смотреть в исходники
Re: Как выглядит class (схема)
Добавлено: 29.05.2017 21:55:34
Лекс Айрин
zub, ну это по любому. Благо, они доступны всегда