Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.04.22;
Скачать: [xml.tar.bz2];

Вниз

Вот завел себе блог   Найти похожие ветки 

 
GrayFace ©   (2007-03-15 17:17) [240]

euru ©   (13.03.07 16:38) [225]
Т.е. добавление полей в хелперы сильно увеличивает громоздкость реализации по сравнению с реализацией хелперов только с методами? Почему?

Хэлпер - это просто сборище функций, тут и реализовывать-то нечего (за исключением добавления синтаксиса)

Пусть в хелперах будут поля, у класса будет некий объем памяти, отведенный под хелперы. Дальше надо каждому хелперу дать смещение его данных относительно начала этого объема.
- Если это зашить в код, то сутуация: 2 пакета, в обоих по хелперу к одному и тому же классу. Оба пакета знают только о своих хелперах, значит у обоих смещение данных хелпера будет 0.
- Значит надо создавать переменную со смещением хелпера, при компиляции и дин. загрузке пакета ее заполнять и при каждом вызове метода хелпера к ней обращаться.
Теперь как можно добавить сам объем.
- Для каждого класса нужна будет переменная с размером этого блока. Опять же должна будет зполняться при динамической зарузке или компилянии программы.
Теперь возникают проблемы с самим заполнением этих переменных. Хотя вроде решаемо, придется менять vmt*, менять NewInstance, InitInstance, но вроде возможно.

Но виртуальные функции переопределять хелперам уж точно не получится, применение хелперов по-прежнему будет редким, соответственно возникает вопрос - нафига?


 
euru ©   (2007-03-16 01:22) [241]

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

1. Создадим модуль, содержащий класс, к которому в дальнейшем присоединим хелпер.
unit u1;

interface

type
  TA = class
  end;

implementation
end.


2. Создадим модуль, содержащий хелпер к этому классу.
unit u2;

interface

uses u1;

type
  TB = class helper for TA
    Field: Integer;
    procedure DoWork();
  end;

implementation
end.


3. Создадим модуль, использующий класс с хелпером.
unit u3;

interface

uses u1, u2;

procedure SetField(a: TA; value: Integer);

implementation

procedure SetField(a: TA; value: Integer);
begin
  a.Field := value;
end;

end.


Теперь напишем программу, в которой якобы может возникнуть коллизия.
program p1;

uses u1, u3;

var a: TA;

begin
  a := TA.Create();
  SetField(a, 5);
end;


Модуль u2, содержащий хелпер, в программе необъявлен. Но это не помешает компилятору учесть наличие хелпера в классе, потому что его присутсятвие определяется косвенно через модуль u3, в котором есть ссылка модуль u2, содержащий хелпер.


 
euru ©   (2007-03-16 01:35) [242]


> GrayFace ©   (15.03.07 17:17) [240]
Соглашусь, что реализация хелперов с полями будет сложнее реализации без них. Правда, пока не уверен, что она будет выглядить так громоздко.

Но пока меня интересует другой вопрос. Возможна ли в принципе реализация хелперов с полями?


> Но виртуальные функции переопределять хелперам уж точно
> не получится
Однозначно?


 
jack128 ©   (2007-03-16 01:52) [243]

euru ©   (16.03.07 1:22) [241]
Гм. Такое очущение, что ты не читал, то что написал vuk и я.  Пока дело какается монолитной программы - вопросов нету. Проблемы возникнут, когда используются ран тайм пакеты.


 
GrayFace ©   (2007-03-16 16:22) [244]

euru ©   (16.03.07 1:35) [242]
Соглашусь, что реализация хелперов с полями будет сложнее реализации без них. Правда, пока не уверен, что она будет выглядить так громоздко.

А я уверен, что она будет выглядеть более громоздко.


 
Суслик ©   (2007-03-16 16:34) [245]


> [243] jack128 ©   (16.03.07 01:52)
> euru ©   (16.03.07 1:22) [241]
> Гм. Такое очущение, что ты не читал, то что написал vuk
> и я.  Пока дело какается монолитной программы - вопросов
> нету. Проблемы возникнут, когда используются ран тайм пакеты.

уж прости :) сам люблю опечатки, но у тебя получилось офигительней моих в 100 раз :)


 
jack128 ©   (2007-03-16 21:15) [246]

Суслик ©   (16.03.07 16:34) [245]
но у тебя получилось офигительней моих в 100 раз :)

Ну дык!  Стараемся.  Растём над собой, так сказать ;-)


 
euru ©   (2007-03-19 02:26) [247]


> jack128 ©   (16.03.07 01:52) [243]
> Такое очущение, что ты не читал, то что написал vuk и я.
Почему не читал? Читал. Но ведь это просто предположение, ничем не подтверждённое. С таким же успехом я могу утверждать, что не будет никаких проблем с использованием хелперов в динамически загруженных пакетах. В пользу своего утверждения я привёл пример. В ответ не получил ни указаний ошибок в моих рассуждениях, ни контрпримеров, доказывающих ваши утверждения.


> vuk ©   (15.03.07 00:28) [234]
> А если так: экземпляр по цепочке вызовов передается невесть
> куда в пакет (например динамически загруженный) и уже там
> на него навешивается хелпер. Что делать-то?
Насколько я понимаю, может быть две ситуации.
1. В программе создаётся хелпер для класса, объявленного в пакете. Использование объектов такого класса с хелпером в самой программе проблем не вызовет (см. [241]). Передача таких объектов в пакет тоже ни к чему криминальному не приведёт. В пакет передастся только та часть объекта, которая используется в пакете. А как с ней работать, пакет знает.

2. Хелпер для типа, используемого в программе, создаётся в пакете. Если я не ошибаюсь, для организации взаимодействия с пакетом создаётся модуль, в котором описывается интерфейс этого пакета. Если описание сделано корректно, то компилятору будет известна информация о наличие хелпера в пакете, и он учтёт её при создании объектов.


> А скорость доступа к данным является аргументом?
Нет. К языку программирования он никакого отношения не имеет.


> jack128 ©   (15.03.07 01:46) [235]
> затем, что раз есть в хелпере есть поле, то оно должно быть
> во всех классах.  В том числе и тех, что были созданы кодом
> внутри пакета.
А если я перефразирую так: раз в потомке есть поле (класс с хелпером фактически является потомком оригинального класса), то оно должно быть во всех классах. В том числе и в его предках (оригинальный класс в пакете фактически является предком для класса с хелпером в программе).
Это будет правильным утверждением?


 
euru ©   (2007-03-19 02:46) [248]


> GrayFace ©   (15.03.07 17:17) [240]
А если так.
Класс знает список всех добавленных когда-либо к нему хелперов. При создании объекта у него заполняется список только тех хелперов, которые реально использовались для этого объекта.

Теперь обращение к элементам хелпера объекта приведёт к следующим шагам:
1. Поиск идентификатора хелпера среди всех хелперов класса.
2. Поиск найденного идентификатора хелпера среди хелперов объекта.
3. Если такой идентификатор у объекта не найден, то выдать сообщение об ошибке.
4. Если хелпер у объекта есть, то взять идентификатор этого хелпера в объекте.
5. Адрес к данным объекта, добавленным хелпером, найти в таблице на пересечении идентификаторов хелпера класса и объекта.


> Но виртуальные функции переопределять хелперам уж точно
> не получится
А, например, подменить в vmt адрес виртуальной функции класса адресом функции хелпера?


 
GrayFace ©   (2007-03-19 20:32) [249]

euru ©   (19.03.07 2:26) [247]
В пользу своего утверждения я привёл пример.

Где??

euru ©   (19.03.07 2:26) [247]
класс с хелпером фактически является потомком оригинального класса

Теперь все ясно, ты ничего не понял о хелперах. Хелпер динамически подключается к классу, в том числе к классу из пакета. Пакет не будет сам по себе создавать объекты "класса с хелпером".

euru ©   (19.03.07 2:46) [248]
3. Если такой идентификатор у объекта не найден, то выдать сообщение об ошибке.

Т.е. при любой попытке использовать хелпер будет ошибка? А то кто ж добавит его идентификатор к хелперам объекта?

euru ©   (19.03.07 2:46) [248]
5. Адрес к данным объекта, добавленным хелпером, найти в таблице на пересечении идентификаторов хелпера класса и объекта.

3D таблица со всеми хелперами, классами и объектами? :)))

euru ©   (19.03.07 2:46) [248]
А, например, подменить в vmt адрес виртуальной функции класса адресом функции хелпера?

А как определить, кто из хелперов "главнее"?


 
jack128 ©   (2007-03-20 01:56) [250]

euru ©   (19.03.07 2:26) [247]
раз в потомке есть поле (класс с хелпером фактически является потомком оригинального класса

нет, класс с хелпером - это не потомок класса.
euru ©   (19.03.07 2:26) [247]
раз в потомке есть поле , то оно должно быть во всех классах.

Что за бред???

Вообще ПРИНЦИПИАЛЬНО реализовать, то что ты хочешь - можно.  Но на практиче - это с одной стороны будет весьма сложно для  разработчиков компилятора, с другой - доступ к этим полям будет весьма и весьма тормознутым. Короче - нафиг надо.  Кому это реально нужно, те без проблем смогут сами все это реализовать, благо в дельфе все для этого есть.


 
euru ©   (2007-03-20 15:26) [251]


> GrayFace ©   (19.03.07 20:32) [249]

> Где??
Здесь - [241].


> Теперь все ясно, ты ничего не понял о хелперах.
О каких хелперах? Которые в Delphi? Так о них вроде бы уже всё выяснили. Я же о других хелперах говорю. Тех, которые добавляют к классу не только методы, но и поля. А это явно не просто динамическая привязка методов хелпера к классу.


> Пакет не будет сам по себе создавать объекты "класса с хелпером".
А вот товарищи vuk и jack128 считают иначе - см. [234] и [235].


> Т.е. при любой попытке использовать хелпер будет ошибка?
>  А то кто ж добавит его идентификатор к хелперам объекта?
Компилятор обладает всей необходимой информацией, которая позволит ему правильно инициализировать список хелперов объекта при его создании.


> 3D таблица со всеми хелперами, классами и объектами? :)))
А 2D-таблица vmt со всеми классами и методами улыбки не вызывает?


> А как определить, кто из хелперов "главнее"?
А зачем? Совпадение сигнатуры методов вызовет сообщение об ошибке ещё во время компиляции.

--------------------------------------------------------------------


> jack128 ©   (20.03.07 01:56) [250]



> нет, класс с хелпером - это не потомок класса.
С точки зрения разработчика - не потомок. Программист продолжает использовать тот же класс, что и раньше. Просто у класса появились новые поля и методы. С точки зрения компилятора - потомок. Новую функциональность нельзя просто механически приписать к текущему классу. Хотя бы потому, что в разных модулях могут объявляться разные хелперы к одному и тому же классу. И для контроля правильности их использования компилятору нужно будет как-то их различать. А это можно сделать, создав, например, потомков (недоступных разработчику) от оригинального класса для всех используемых вариантов с хелперами.


> Что за бред???
А требование наличия хелперов во всех пакетах, даже там, где они изначально не были предусмотрены, не бред?


> Вообще ПРИНЦИПИАЛЬНО реализовать, то что ты хочешь - можно.
>   Но на практиче - это с одной стороны будет весьма сложно
> для  разработчиков компилятора, с другой - доступ к этим
> полям будет весьма и весьма тормознутым. Короче - нафиг
> надо.
Чем-то напоминает утверждения 15-20-летней давности о необходимости в языках средств ООП.


> Кому это реально нужно, те без проблем смогут сами все это
> реализовать, благо в дельфе все для этого есть.
А вот можно увидеть пример текущей дельфийской реализации хелперов в Delphi 7 и ниже средствами самого языка? И если это действительно можно, то зачем тогда они были введены?


 
GrayFace ©   (2007-03-23 21:57) [252]

euru ©   (20.03.07 15:26) [251]
Здесь - [241].

Это ж не кусок реализации. Даже не пример когда это нужно.

euru ©   (20.03.07 15:26) [251]
А вот товарищи vuk и jack128 считают иначе - см. [234] и [235].

Нет, так же.

jack128 ©   (20.03.07 1:56) [250]
Но на практиче - это с одной стороны будет весьма сложно для  разработчиков компилятора, с другой - доступ к этим полям будет весьма и весьма тормознутым.

Думаю, можно сделать и без особых временных затрат на доступ, но проблем по горло.

euru ©   (20.03.07 15:26) [251]
А 2D-таблица vmt со всеми классами и методами улыбки не вызывает?

Конечно нет. Объектов могут быть тысячи.

euru ©   (20.03.07 15:26) [251]
А зачем? Совпадение сигнатуры методов вызовет сообщение об ошибке ещё во время компиляции.

Пакеты компилируются отдельно друг от друга и могут подключаться к программе динамически.

euru ©   (20.03.07 15:26) [251]
С точки зрения разработчика - не потомок. Программист продолжает использовать тот же класс, что и раньше. Просто у класса появились новые поля и методы. С точки зрения компилятора - потомок. Новую функциональность нельзя просто механически приписать к текущему классу. Хотя бы потому, что в разных модулях могут объявляться разные хелперы к одному и тому же классу. И для контроля правильности их использования компилятору нужно будет как-то их различать. А это можно сделать, создав, например, потомков (недоступных разработчику) от оригинального класса для всех используемых вариантов с хелперами.

Ну вот ты сам сказал, что хелперы с полями невозможны (хотя это не совсем так) или будут непонятно чем. См. то что выделено жирным. Объект может создаваться в одном пакете, а в другом - использоваться хелпер к такому же классу. В твоей схеме в этом случае велетит ошибка? Тогда скажи, зачем программист будет писать хелперы к своим классам, вместо того чтобы создать потомка? Ведь для чужих пакетов он хелперов написать не сможет.


 
euru ©   (2007-03-25 03:39) [253]


> GrayFace ©   (23.03.07 21:57) [252]
> Тогда скажи, зачем программист будет писать хелперы к своим
> классам, вместо того чтобы создать потомка?
Думаю, это основной вопрос.

С моей точки зрения, наследование -- это экстенсивный путь развития объектной модели. В общем случае добавление в ней новых свойств требует появление новых классов-потомков, которые бы эти свойства реализовали. При этом чем более древовидна модель, тем больше появится потомков, реализующих эти свойства. Для избежания возникающего при этом дублирования кода часто приходится пересматривать иерархию и либо добавлять новые свойства в классы-предки, либо встраивать в иерархию промежуточные классы. В первом случае появляются монстроидальные классы (типа TControl), которые содержат в себе множество бесполезной для их уровня информации. Во втором случае появляются лишние абстрактные классы, также не имеющие пользы и только загромождающие иерархию.

Теоретически (по крайней мере, о реализации я не слышал) существует также интенсивный путь развития модели. По мере появления у объектной модели новых свойств они оформляются в виде отдельных специальных классов, которые по мере необходимости присоединяются к основным классам на любом уровне иерархии, обеспечивая требуемую функциональность для объектов этого класса и его потомков.

Примеры применения (на примере VCL) таких классов я уже приводил выше, но повторю их ещё раз:
1. Поле PasswordChar в классе TEdit. Очень редко используемое поле. Вынеся его во вспомогательный класс можно было бы добавлять это поле (и соответствующее поведение) только к тем объектам TEdit, которым оно действительно нужно.
2. Свойство Dockable у класса TControl. Тоже не для всех контролов и не во всех проектах используется. Также можно вынести в отдельный класс и подключать по мере необходимости.
3. Дублирование обычных контролов и DB-контролов. DB-функциональность можно было бы вынести в отдельный вспомогательный класс и подключать его к нужным обычным контролам.

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

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

P.S.: Кстати, кроме наследования (вертикального связывания классов) существует ещё и горизонтальное связывание, реализуемое в аспектно-ориентированных языках. Спасибо vuk"у, который в соё время дал ссылки на такие языки. В сравнении с этими способами связывания хелперы можно назвать внутренним связыванием, реализующим саморазвитие классов.



Страницы: 1 2 3 4 5 6 7 вся ветка

Форум: "Прочее";
Текущий архив: 2007.04.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 1.04 MB
Время: 0.079 c
2-1175512529
Dmitry_177
2007-04-02 15:15
2007.04.22
отобразить все файлы находящиеся в папке


2-1175260650
Greenchel
2007-03-30 17:17
2007.04.22
http, ftp и т.д.


4-1164645015
Альберт
2006-11-27 19:30
2007.04.22
получение хэндла окна из TShellExecuteInfo


6-1161869306
Axis_of_Evil
2006-10-26 17:28
2007.04.22
TWSocket. как получить уведомление о невозможности соединения?


1-1172650540
Oleg_teacher
2007-02-28 11:15
2007.04.22
сокеты





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский