Comments 27
Поздравляю, вы открыли для себя COM. Верее, тот факт, что объекты в Delphi частью своей внутренней структуры (по положительному смещению от указателя) соответствуют формату COM-объектов.
соответствие формату ком объектов тут вообще не при делах. Важен только автоматический вызов методов AddRef/Release.
Автоматический вызов AddRef/Release как раз и сделан для полного соответствия COM-механизмам и невозбранного использования Delphi-объектов как объектов COM. Для того же, для чего и структура соответствует
Как-то сложно инициализируется. Помоему забыть написать MyOb := CreateObjectDestroyer() не сложнее, чем MyOb.Free; в конце.
В любом случае ЧТО ТО писать нужно.
Хотя для _старших_ версий дельфи есть вариант писать:
begin
MyObj := TMyObj.Create;
MyObj.DoWork();
end; // тут объект будет уничтожен
но на мой взгляд — это неочевидное решение. В коде как то должно быть обозначено, что объект сам разрушется. В моем варианте вызов CreateObjectDestroyer — явное указание на это
Хотя для _старших_ версий дельфи есть вариант писать:
begin
MyObj := TMyObj.Create;
MyObj.DoWork();
end; // тут объект будет уничтожен
но на мой взгляд — это неочевидное решение. В коде как то должно быть обозначено, что объект сам разрушется. В моем варианте вызов CreateObjectDestroyer — явное указание на это
Я боюсь напутать за давностью лет :)
Если в самом классе реализовать интерфейс, он тоже будет автоматически уничтожатся.
Кажется в каком-то парсере XML это реализовано. Конечно, это не подойдет для существующих классов.
Если в самом классе реализовать интерфейс, он тоже будет автоматически уничтожатся.
Кажется в каком-то парсере XML это реализовано. Конечно, это не подойдет для существующих классов.
>>Если в самом классе реализовать интерфейс, он тоже будет автоматически уничтожатся.
О, это тоже тонкий момент, все зависит от того, как этот класс использовать
var
Obj: TInterfacedObject; // реализатор IUnknown
begin
Obj := TInterfacedObject.Create;
end // Obj — не уничтожится. Будет мем лик.
в данном примере нету присвоений объекта к интерфейсной ссылке, поэтому не будет вызваны AddRef/Release, счетчик ссылок не работает и мы имеем грабли.
О, это тоже тонкий момент, все зависит от того, как этот класс использовать
var
Obj: TInterfacedObject; // реализатор IUnknown
begin
Obj := TInterfacedObject.Create;
end // Obj — не уничтожится. Будет мем лик.
в данном примере нету присвоений объекта к интерфейсной ссылке, поэтому не будет вызваны AddRef/Release, счетчик ссылок не работает и мы имеем грабли.
Так много уже где делают. Например, в JVCL работа с классами-контейнерами построена полностью на интерфейсах. Ну и, конечно, c MSXML тоже удобнее работать через интерфейсы, но там все-таки COM…
Я делал синтаксис with Using(MyObject, TMyObject.Create) do… а-ля C#. Причем можно и просто Using — кому как понятнее. Тем не менее для команды не покатило — плохо читалось другими разработчиками.
Я думал что Делфи уже давно умер.
А он оказывает еще жив!
А он оказывает еще жив!
Зачем? Какой смысл в этом? Неужели так сложно запомнить «создал — освободи». Смысл в этом диком нечитабельном огороде, который лишь засоряет чистейший эфир кода?
try/except обертка вокруг (из примера «как делали до меня») — это вообще не красиво. Долой exception'ы!
Указанный вами подход упоминается на delphi-сайтах года с 2000 точно, в том или ином исполнении.
try/except обертка вокруг (из примера «как делали до меня») — это вообще не красиво. Долой exception'ы!
Указанный вами подход упоминается на delphi-сайтах года с 2000 точно, в том или ином исполнении.
Статья познавательная, но очень много грамматических и синтаксических ошибок. Режет глаз при чтении. :)
Прислушайтесь к pasha_golub, пользуйтесь каким-либо редактором: и красивее будет, и ошибки проверите автоматически.
Прислушайтесь к pasha_golub, пользуйтесь каким-либо редактором: и красивее будет, и ошибки проверите автоматически.
Интересно. Я что то похожее давно пытался сделать, но не прижилось. Не из-за указанных недостатков. Просто для одних действий мне проще сделать with TClass.Create do try DoWorck finally Free; end; а в основном делаю интерфейс и работаю с объектом через него. Да и случаи когда надо локально создавать и освобождать объект не так часто встречаются.
FYI, в Jedi Code Library есть аналогичные классы и функции =)
Конечно это напоминает COM, тут и фабрика класса и реализация интерфейса на основании подсчета количества ссылок, но реально под задачу описанную в примере — подсчет ссылок не нужен. Нужен аналог С++ шаблона (извините, не помню есть ли такое в делфи — 100 лет в делфи не программил), т.е. некий класс который сам создаваясь на стеке создает экземпляр нужного нам объекта в куче. Когда первый объект вылетит из зоны видимости, он сам будет уничтожаться (он ведь в стеке) ну и в деструкторе должен потянуть за собой уничтожение объекта из кучи.
Подсчет ссылок нужен тогда, когда мы совсем отпускаем объект в свободное плавание, передаем его в разные функции, маршалим его между потоками и т.п. тут он уничтожается неявно когда становится не нужен. И тут возникает как раз проблема создания фабрики классов и автоматического удаления, чтобы и операция создания и операция удаления была сделана одним и тем же рантаймом.
Автору топика +1 за изобретательность.
Подсчет ссылок нужен тогда, когда мы совсем отпускаем объект в свободное плавание, передаем его в разные функции, маршалим его между потоками и т.п. тут он уничтожается неявно когда становится не нужен. И тут возникает как раз проблема создания фабрики классов и автоматического удаления, чтобы и операция создания и операция удаления была сделана одним и тем же рантаймом.
Автору топика +1 за изобретательность.
Создавать интерфейсы и так извращаться вместо try finally end? Нет, извините, try finally end мне нравится больше.
Sign up to leave a comment.
Дельфи. Автоматическое уничтожение объектов по выходу из метода