
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.218] |
![]() |
|
Страницы: (245) « Первая ... 219 220 [221] 222 223 ... 244 245 ( Перейти к последнему сообщению ) |
Сообщ.
#3301
,
|
|
|
На nil в деструкторе проверяется все (причем неявно как правило, т.к. внутри Free эта проверка заложена уже) из-за возможности исключения в конструкторе. Если в дельфи при вызове конструктора происходит исключение, то вызывается деструктор, чтобы освободить все то, что успело создаться в конструкторе до исключения - сборщика мусора то нет. Так вот, если на момент исключения в конструкторе что-то еще не создалось, то только в этом случае нужна проверка на nil. Поэтому Free вместо Destroy и пишут, т.к. Free это if Self <> nil then Destroy. С другим, где бы это было нужно, я на практике не встречался. Добавлено Ты понимаешь разницу между объектом и ссылкой на объект? Объект не может становиться nil, он может только уничтожиться. А ссылка может стать равной nil. А ссылок может быть несколько на один и тот же объект и волшебным образом их никто при уничтожении не обнулит, т.к. рантайм нигде не хранит все ссылки на объекты. |
Сообщ.
#3302
,
|
|
|
Цитата --Ins-- @ Так вот, если на момент исключения в конструкторе что-то еще не создалось, то только в этом случае нужна проверка на nil. Ох, фак ![]() |
![]() |
Сообщ.
#3303
,
|
|
Цитата --Ins-- @ Если в дельфи при вызове конструктора происходит исключение, то вызывается деструктор, чтобы освободить все то, что успело создаться в конструкторе до исключения - сборщика мусора то нет. Так вот, если на момент исключения в конструкторе что-то еще не создалось, то только в этом случае нужна проверка на nil. После плюсов это кажется дикостью ![]() |
Сообщ.
#3304
,
|
|
|
Цитата --Ins-- @ На nil в деструкторе проверяется все (причем неявно как правило, т.к. внутри Free эта проверка заложена уже) из-за возможности исключения в конструкторе. Зачем тогда FreeAndNil ? Мне не понятно зачем занулять указатель на объект перед вызовом деструктора? Почему не Free и потом зануление? Видимо всетаки возможны ситуации , и они не так уж и редки, когда в деструкторе имеем уничтоженый, но не зануленный объект? |
Сообщ.
#3305
,
|
|
|
Даже если бы и существовала возможность устанавливать все ссылки в nil автоматически послу уничтожение объекта - все равно это было бы говно. Я не сторонник проверять, уничтожен ли объект или нет по проверке ссылки на nil, я предпочитаю чтобы при уничтожении объекта все заинтересованные получали об этом уведомления и сами предпринимали нужные действия, которые обнулением ссылки могут не ограничиваться |
Сообщ.
#3306
,
|
|
|
Вот например оригинал статьи про FreeAndNil. Так вот там автор утверждает что Free оцтой и ведет к скрытым ошибкам и приводит в пример к каким.
Цитата http://www.gunsmoker.ru/2009/04/freeandnil-free.html Многие говорят, что опытный программист может ставить FreeAndNil только там, где это необходимо. Если грамотно использовать объекты (например, уничтожать объекты исключительно в деструкторе), то не будет нужды в FreeAndNil. Но это не верно. Вы не можете этого знать. Представим, что в деструкторе объекта (объект-контейнер) мы удаляем объектное поле с помощью Free. В деструкторе этого поля вызывается виртуальный метод, который ничего не делает в базовом классе, а в каком-то далёком предке вызывает последовательность действий, которая приводит к вызову виртуального-же метода объекта-контейнера. Который, в свою очередь, в каком-нибудь далёком предке (ошибочно) обращается к нашему удаляемому полю. При этом, обращение проходит на ура, но общее состояние становится безвозвратно испорченным. Упс. |
![]() |
Сообщ.
#3307
,
|
|
Цитата --Ins-- @ Ты понимаешь разницу между объектом и ссылкой на объект? Объект не может становиться nil, он может только уничтожиться. А ссылка может стать равной nil. А ссылок может быть несколько на один и тот же объект и волшебным образом их никто при уничтожении не обнулит, т.к. рантайм нигде не хранит все ссылки на объекты. Действительно. FreeAndNil их тоже волшебным образом не обнулит: ![]() ![]() type TFoo = class public Value: Integer; end; var a, b: TFoo; procedure CheckNil(v: TObject); begin if v = nil then WriteLn('True') else WriteLn('False'); end; begin a := TFoo.Create; b := a; FreeAndNil(a); CheckNil(a); CheckNil(b); b.Value := 2; WriteLn(b.Value); ReadLn; end. ![]() ![]() True False 2 Деструкторы такие деструкторы. |
Сообщ.
#3308
,
|
|
|
Цитата Flex Ferrum @ У него руки-ноги уже отрублены, но сердце еще стучит... А еще столько дел сделать надо. Например, завещание написать. Формально - да. Т. е. объект "физически" ещё существует. Но вот существует ли он логически? |
Сообщ.
#3309
,
|
|
|
Цитата Wound @ Зачем тогда FreeAndNil ? Спроси у адептов FreeAndNil, я то тут причем ![]() |
Сообщ.
#3310
,
|
|
|
Цитата В деструкторе этого поля вызывается виртуальный метод, который ничего не делает в базовом классе, а в каком-то далёком предке вызывает последовательность действий, которая приводит к вызову виртуального-же метода объекта-контейнера. Полиморфизм в конструкторах/деструкторах во всей своей извращённой красоте... |
Сообщ.
#3311
,
|
|
|
Цитата --Ins-- @ Спроси у адептов FreeAndNil, я то тут причем ![]() Адепты FreeAndNil говорят что ты не можешь не написать код так, чтобы FreeAndNil не был необходим. Вернее ты не можешь быть уверен что ты написал хороший код, если не использовал FreeAndNil. И там же по ссылке он приводит аргументацию. |
Сообщ.
#3312
,
|
|
|
Цитата korvin @ FreeAndNil их тоже волшебным образом не обнулит: Совершенно верно, он обнулит только ту ссылку, что ему туда запихнут. От этого практической пользы еще меньше. nil вообще не должен быть индикатором, что объект уничтожен. |
Сообщ.
#3313
,
|
|
|
Цитата --Ins-- @ Совершенно верно, он обнулит только ту ссылку, что ему туда запихнут. Погоди, в примере korvin, переменные a и b указывают на разные места? ![]() ![]() |
Сообщ.
#3314
,
|
|
|
Цитата Wound @ Вернее ты не можешь быть уверен что ты написал хороший код, если не использовал FreeAndNil. И там же по ссылке он приводит аргументацию. Могу ![]() ![]() Добавлено Цитата Wound @ переменные a и b указывают на разные места? Нет Цитата Wound @ Почему результат разный? a := 5; b := 5; a := 0; Чему равно b? Почему оно тоже должно стать 0? Оно так и останется 5 |
Сообщ.
#3315
,
|
|
|
Цитата --Ins-- @ Тогда зачем проверки на nil в конструкторах/деструкторах, если это не индикатор? А что является или должно являться индикатором? nil вообще не должен быть индикатором, что объект уничтожен. |