Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Зачем нужен Temp: TObject в функции FreeAndNil ? [D7]


FreeAndNil ©   (2005-02-01 04:38:00) 

procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;


Нельзя просто ? :
TObject(Obj).Free;
Pointer(Obj) := nil;


Sergey_Masloff   (2005-02-01 14:18:00) [1]

GuAV ©   (01.02.05 13:23) [13]
>>Получаем еррор и тут же рубим единственную ниточку к его >>причине - причем рубим гарантированно.
>Разве ?
Ну да. Нашу ссылку мы грохнули имеем эксепшн скажем с адресом. И?
Зачем обнулять ссылку на неразрушеный объект?


GuAV   (2005-02-01 13:25:00) [2]

[8] Ну да, сохранили объект, но потеряли исключение...


GuAV   (2005-02-01 13:23:00) [3]

Sergey_Masloff   (01.02.05 10:24) [7]
Получаем еррор и тут же рубим единственную ниточку к его причине - причем рубим гарантированно.


Разве ?

Это происходило бы если бы Pointer(Obj) := nil; подняло бы своё исключение (эта строка может поднять разве что AV в случае неверного параметра типа TOboject(nil^), тогда Free подняла бы то же самое), а так оригинальное исключение не теряется.

Что касается причин именно такой реализации FreeAndNil - согласен с Amoeba ©.


PVOzerski   (2005-02-01 11:16:00) [4]

2Amoeba ©:
Игорь, а чем плох [8]? "Лишним" блоком try...except? Ну, так не надо в длинные циклы загонять, благо Free не отменял никто.


Amoeba   (2005-02-01 11:07:00) [5]

Посмотрим, что получится, если сделать "по рабоче-крестьянски", как некоторые предлагают. Если Obj указывает чер-те на что, но только не на существующий объект? что тогда? Будет вызвано исключение и присвоения nil этому Obj не произойдет. В борландовском коде этого удается избежать, поскольку Obj обниливается еще до попытки вызова деструктора (Free), так что процедура выполнит свою задачу до того, как будет выполнен код, потенциально опасный возникновением исключения. Использование же try ... finally тоже приемлемо, но это будет более медленным.


Digitman   (2005-02-01 11:06:00) [6]

просто Борланд, очевидно, полагался на осознанный выбор программером между применением Object.Free и FreeAndNil(OvjectRef) в том или ином алгоритмическом случае ..

в первом случае подразумевается, что деструктор потенциально способен возбудить исключение, во втором же подразумевается, что деструктор гарантированно не возбудит исключение


Sergey_Masloff   (2005-02-01 11:02:00) [7]

PVOzerski ©   (01.02.05 10:53) [8]
>Тогда и старый код
Да какой старый. FreeAndNil появилась в D5 и по вышеприведенным соображениям восторга и массового перехода к ее использованию не вызвала. Я и сам ее практически не использовал да и не видел чтобы другие массово применяли. А пару-тройку мест переписать если что не так старшно ИМХО.


PVOzerski   (2005-02-01 10:53:00) [8]

IMHO [5] обладает теми же недостатками, что и оригинал, только будет тормознее. Тогда уж надо было бы делать что-то такое:

function FreeAndNil(var Obj):tObject;
var
 Temp:tObject;
begin
 Temp:=tObject(Obj);
 pointer(Obj):=nil;
 Result:=nil;
 try
  Temp.Free;
 except
  Result:=Temp;
 end;
end;

Тогда и старый код будет компилироваться, и возможная утечка памяти будет отлавливаема с помощью, например, if assigned(FreeAndNil....


Sergey_Masloff   (2005-02-01 10:24:00) [9]

REA   (01.02.05 10:19) [5]
Ну ты че? Получаем еррор и тут же рубим единственную ниточку к его причине - причем рубим гарантированно.


Digitman   (2005-02-01 10:23:00) [10]


> Александр Иванов ©   (01.02.05 10:10) [3]


а, может, в методе-деструкторе некое условие проверяется, и по рез-там проверки возбуждается искл-е, фиксирующее факт недопустимости разрушения объекта при данном условии ?

если бы ссылка не обнулялась, то при исключении, вызванном freeandnil(), можно было бы определить источник искл-я, и если искл-е вызвано отсутствием соотв.условия создать это условие и вновь вызвать freeandnil() .. но так как freeandnil() первым делом обнулила ссылку, повторный ее вызов пройдет "вхолостую" и не разрушит объект, что чревато утечками ..


REA   (2005-02-01 10:19:00) [11]

Логично (если конечно нет какой то специальной логики).
А так?:
Try
 TObject(Obj).Free;
Finally
 Pointer(Obj) := Nil;
End;


Digitman   (2005-02-01 10:18:00) [12]


> REA   (01.02.05 10:05) [2]


нууу.. в целом - да, это не есть корошо ..


Александр Иванов   (2005-02-01 10:10:00) [13]

REA   (01.02.05 10:05) [2]
Если деструктор не может отработать, то зачем нам ссылка, если мы все равно не можем удалить объект?


REA   (2005-02-01 10:05:00) [14]

Что тоже не слишком хорошо - ссылка потеряется, а деструктор не отработает. Или нет?


Digitman   (2005-02-01 08:38:00) [15]


> Нельзя просто ? :
> TObject(Obj).Free;
> Pointer(Obj) := nil;


TObject(Obj).Free; //а если здесь возникнет исключ.ситуация ?
Pointer(Obj) := nil; //тогда эта строчка не выполнится, хотя обниление объектной переменной, по замыслу Борланда, как видно из его кода должно быть безусловным


Наверх

Титульная страница Поиск, карта сайта Написать письмо