![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Стиль: саморазрушение
Igorek © (2002-10-30 20:22:00)Сегодня был такой случай: уничтожается обьект, метод которого в стеке вызовов процедур. Естественно, если после уничтожения мы в этом методе обратились бы к каким-либо полям данного (уже уничтоженного) обьекта - получили бы AccessViolation. К счастью мы этого не сделали и все нормально работает. Но не является ли такой подход признаком плохого стиля?
KSergey (2002-10-31 12:32:00) [21]> Zemal © (31.10.02 11:24)
> Аха :). Фантазии :). Размечтался тут понимаешь-ли :). А
> вообще... Как бы круто было, в натуре, иметь метод в действительности
> определяющий существование объекта (причём любого, а не
> конкретного) в памяти... идилия полнейшая!!! И сразу жить
> хочется...
Не понятно, что тут хорошего, впрочем это легко (как мне кажется) реализуемо: свой менеджер объектов - и вперед! Не так уж и сложно, и главное - все возможности для этого есть.
Zemal (2002-10-31 12:03:00) [22]>> reonid
Ты прав... я напутал :). Действительно Assigned... окончание упустил :). Спасибо за уточнение :). А на счёт "магической проверки на существование тут нет": так я же так и написал, что проверяется не равность ссылки nil и ничего больше :). Про магию я неупоминал! :)
reonid (2002-10-31 11:52:00) [23]2kva (31.10.02 11:38)
>А почему не воспользоваться Form1.Release
А это тоже самое. Только речь шла не только о формах.
reonid (2002-10-31 11:44:00) [24]2Zemal © (31.10.02 11:00)
Assign - это совсем из другой оперы.
а Assigned(x) - это просто x<>nil
(Для процедурных типов @x<>nil).
Никакой магической проверки на существование
объекта тут нет и быть не может.
Igorek © (31.10.02 11:04)
>если обьекта нет - метод просто не вызывается.
Такой "стиль" программирования может привести к
непредсказуемым результатам. (Даже не может, а
безо всякого сомнения приведёт).
Уж лучше пусть эксепшн выдаёт.
kva (2002-10-31 11:38:00) [25]Полностью согласен с Ю.Зотовым, down, Andryk, Anatoly Podgoretsky.
Вопрос Ю.Зотову
> В подобной ситуации я использовал отложенное уничтожение -
> посылкой форме сообщения через PostMessage. То есть, сначала
> завершается вызов метода объекта, а потом он уничтожается
> извне.
> Думаю, так лучше. И не мешает обращаться к полям.
А почему не воспользоваться Form1.Release
Результат тот же, а реализация проще.
Или я чего не понял?
С уважением, Владимир.
Song (2002-10-31 11:32:00) [26]2Юрий Зотов © (31.10.02 00:42)
>>Нет проблем. PostThreadMessage + Application.OnMessage.
А зачем нужен объект TApplication, если нет форм?
Zemal (2002-10-31 11:24:00) [27]Аха :). Фантазии :). Размечтался тут понимаешь-ли :). А вообще... Как бы круто было, в натуре, иметь метод в действительности определяющий существование объекта (причём любого, а не конкретного) в памяти... идилия полнейшая!!! И сразу жить хочется... И писать, писать, писать! хех... ладно, хватит мечтать :).
Igorek (2002-10-31 11:04:00) [28]В идеале должно быть так, что-бы обьект можно было разрушить откуда угодно. И для каждого метода (не классового) предусловием было-б существование обьекта. Т.е. если обьекта нет - метод просто не вызывается. Но это уже фантазии.
Zemal (2002-10-31 11:00:00) [29]Кстати, чтобы корректно обработать такую ситуацию есть простая конструкция определения существования объекта.
if Assign(Source: TPersistent) then ...
Но это также не предупредит разрушения объекта во время выполнения процедуры (если она длительная) :(. Это я к тому, что если есть потоки... Да и в общем-то надо учесть, что Assign проверяет не существование объекта, а лишь ссылку (не равна ли она nil)... вот в общем-то и всё что он делает :(. Так что вариант: разрушать объекты, как было сказано выше, надо FreeAndNil(TObject)... это гарантированно разрушит объект и присвоит ссылке значение равное nil. Удачи!
Igorek (2002-10-31 10:55:00) [30]
> Толик © (31.10.02 10:40)
но зачем же Boralnd так настоёчиво предлагает использовать
> глобальные переменные?
Потому, что Обжект Паскаль - примитивный язык (нет статических переменных, нет областей видимости).
Только не кидайтесь памидорами :-)
Толик (2002-10-31 10:40:00) [31]to Anatoly Podgoretsky © (31.10.02 09:10)
Абсолютно в Вами согласен, насчёт удаления Var Form1: TForm1; из модуля формы, да и вообще любых глобальных переменных, но зачем же Boralnd так настоёчиво предлагает использовать глобальные переменные? (понимаю, что вопрос не лично к Вам), да и создать главную форму приложения (Application.MainForm) без глобальной переменной надо ещё понять как сделать...
SVM (Perm) (2002-10-31 10:03:00) [32]Зачем присваивать Nil? Иногда нужно бывает проверять,
создан ли объект, если нет (Nil), то создать и инициализировать
переменную. К тому же, объект может несколько раз уничтожаться
(FreeAndNil), а затем создаваться снова.
Anatoly Podgoretsky (2002-10-31 09:10:00) [33]KSergey © (31.10.02 08:45)
См. Юрий Зотов © (31.10.02 00:42)
Наличие глобальных указателей на объект приводит к ошибка и к искушению повторно использовать переменные, результат один неустойивая программ с трудно обнаруживаемыми ошибками.
Далее ты и сам ссылаешься на Obj:=nil; данная строка предполагае, что переменная Obj будет использоваться повторно где нибудь в конструкциях типа if Assifned(Obj) then ...
Часты также ошибки следующего рода, допустим у нас есть форма TForm1 и соответствующая переменная Form1. В программах при этом часто встречается конструкция
Procedure ....
Var
Form1: TForm1;
begin
Form1 := TForm1.Create
и где то в другом месте обращение к глобальной переменной Form1.xxx ужасть, искать тяжело.
Первое что надо сделать в модуле формы удалить Var Form1: TForm1;
KSergey (2002-10-31 08:45:00) [34]Что за блажь уничтожать объектом самого себя?! Разве он себя создавал? Нет. Создавался он извне. Так значит и уничтожить надо извне.
to Anatoly Podgoretsky © (31.10.02 00:42)
Ой, а еще раз русской речью можно? ;) вроде буквы то русские, но я ничего не понял....
> Cobalt © (31.10.02 00:35)
> Предполагаю, что один из доводов Против саморазрушения объекта
> - то, что он не может установить указатель на себя в Nil.
Люди! Зачем присваивать переменной-ссылке nil? Я никогда этого не делаю, может я что-то недопонмаю? Часто в примерах вижу места, когда написано:
Obj.Free;
Obj:=nil;
и далее Obj нигде не используется (а то и вообще конец ф-ции). Зачем?! Дурацкая привычка?
Anatoly Podgoretsky (2002-10-31 00:42:00) [35]Это только плюс, глобальные в могилу, источник неприятностей, для работыы как правило ссылки, за редким исключением не нужны
Юрий Зотов (2002-10-31 00:42:00) [36]> Cobalt © (31.10.02 00:35)
1. Такого указателя может вообще не быть.
2. Таких указателей (на один и тот же объект) может быть сколько угодно много.
3. Такие указатели к самому объекту не относятся, а за какие-то там внешние переменные он не отвечает и НИЧЕГО с ними делать не должен.
Cobalt (2002-10-31 00:35:00) [37]Предполагаю, что один из доводов Противсаморазрушения объекта - то, что он не может установить указатель на себя в Nil.
down (2002-10-31 00:30:00) [38]> нужно связывать объект с формой
Совершенно не обязательно.
- Ну не с формой, так с другим объектом, причем связь получается притянутой за уши.
> и навороченно слишком
IMHO, это нормальный уровень прикладного программиста.
- Если можно сделать проще, то нужно делать проще, мы ведь говорим о стиле.
> который может, например, использоваться в бесформенном приложении.
Нет проблем. PostThreadMessage + Application.OnMessage.
- Пример я привел неверный, правильный - консольное приложение
> Вообще же, я привел этот пример не как абсолютное решение,
> а именно как пример обхода нежелательной ситуации.
- Я же просто хотел сказать, что, ИМХО, такой способ не есть гут и лично я бы в общем случае предпочел уничтожать объект именно изнутри. Вообще, конечно, нужно думать и применять то, что в конкретной задаче более целесообразно.
Юрий Зотов (2002-10-30 23:54:00) [39]> нужно связывать объект с формой
Совершенно не обязательно.
> и навороченно слишком
IMHO, это нормальный уровень прикладного программиста.
> который может использоваться в бесформенном приложении.
Нет проблем. PostThreadMessage + Application.OnMessage.
Вообще же, я привел этот пример не как абсолютное решение, а именно как пример обхода нежелательной ситуации. Скажем, таким же образом можно выгружать DLL, из которой показана модальная форма, но, наверное, могут встретиться и ситуации, когда этот способ окажется неприемлем.
down (2002-10-30 23:01:00) [40]Одно дело форма, другое - какой-то отвлеченный объект, который может, например, использоваться в бесформенном приложении. Правоту Юрия я не оспариваю(потому и написал - "по моему скромному мнению"), иногда, может быть, его способ - хорошее решение.