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

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

отличия Assign от p<>nil


Страницы:   1 2

денизко ©   (2007-10-09 17:24:00) 

Объясните дураку зачем нужна ф-ция Assign, если можно написать
if p<>nil then ...

 И как все таки узнать был ли убит объект, если после вызова деструктора Free, переменная-объект по-прежнему не nil и указывает на недоступный кусок памяти?


денизко   (2007-10-09 20:26:00) [21]


> MetalFan ©

 О! А можно поподробней? Что находится по адресу LongInt(P) - 4


Johnmen   (2007-10-09 19:41:00) [22]

Солидарен с Суслик ©   (09.10.07 18:25) [11], так удобней.


MetalFan   (2007-10-09 19:18:00) [23]

нет, лучше такое:
function CheckIsFreed( AObject: TObject ): Boolean;
var
 Signature: PLongInt;
 P: Pointer;
begin
 P := AObject;
 Result := P = nil;
 if Result then Exit;
 Signature := PLongInt(LongInt(P) - 4);
 Result := IsBadReadPtr( Signature, 4 );
 if result then Exit;
 Result := Signature^ = 1;
end;

и тесткод:
procedure TForm1.Button1Click(Sender: TObject);
var
 lSL : TStringList;
begin
 Integer(lSL) := 123123123;
 ShowMessage( BoolToStr( CheckIsFreed( lSL), True ));
 lSL := TStringList.Create;
 ShowMessage( BoolToStr( CheckIsFreed( lSL), True ));
 lSL.Free;
 ShowMessage( BoolToStr( CheckIsFreed( lSL), True ));
end;


MetalFan   (2007-10-09 19:15:00) [24]

а как вам нечто такое?
function CheckIsFreed( AObject: TObject ): Boolean;
var
 Signature: PLongInt;
 P: Pointer;
begin
 P := AObject;
 Result := P = nil;
 if Result then Exit;
 Signature := PLongInt(LongInt(P) - 4);
 Result := Signature^ = 1;
end;


Суслик   (2007-10-09 18:25:00) [25]


>  [9] Ega23 ©   (09.10.07 18:02)
> > в многопоточном можно нарваться, хотя и маловероятно
> Это как?????


я нарывался как в [10] описано.

------------
по сабжу - я не пишу Assigned никогда, всегда <> nil пишу.
удобней мне так


clickmaker   (2007-10-09 18:07:00) [26]

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

сравни последовательность операций.
Представь, что деструктор начал выполняться, а другой поток с чистой совестью, проверив, что <> nil, полез работать с объектом...


Ega23   (2007-10-09 18:02:00) [27]


> в многопоточном можно нарваться, хотя и маловероятно


Это как?????


clickmaker   (2007-10-09 18:00:00) [28]


> можно тупо заменить на
> Obj.Free;
> Obj := nil;

в многопоточном можно нарваться, хотя и маловероятно


Ega23   (2007-10-09 17:55:00) [29]


> Второй вопрос открыт: известны ли кому-нибудь способы, как
> узнать был ли убит объект, если он был убит НЕ FreeAndNil
> а банальным деструктором Free?


Перехват исключения.
А вообще - просто не следует такого допускать ещё при проектировании.
И, кстати, FreeAndNil(Obj) можно тупо заменить на
Obj.Free;
Obj := nil;


денизко   (2007-10-09 17:49:00) [30]

Тьфу, не Assign, Assigned конечно.. торопился..


> Сергей М.
> Если возникло исключение EAccessViolation

 т.е. бороться с ним в блоке try except? смущает громоздкий код:
 если б Assigned позволяла определить существование объекта я бы обошелся одной лаконичной строкой:
 if Assigned(p) then p.DoIt;

с try except будет 4:

 try
   p.DoIt;
 except
 end;

 можно конечно все в одну уложить но... не нравится и все тут! :)


Правильный Вася   (2007-10-09 17:48:00) [31]


> ф-ция Assign

вообще-то это метод, и делает он вещи прямо противоположные описанным тобой


Сергей М.   (2007-10-09 17:43:00) [32]


> известны ли кому-нибудь способы, как узнать был ли убит
> объект


Нет иных способов, нежели перехват исключения.

Да и не надо ничего узнавать, просто не следует допускать "убийство" объекта без соответствующей немедленной коррекции всехсуществующих ссылок на него.


денизко   (2007-10-09 17:36:00) [33]


> clickmaker ©

 Спасибо за ответ.
 Хелп я читал и с FreeAndNil знаком.
 
 Т.е. получается что Assigned только для того и нужна, чтобы в нее можно было пихать как указатели так переменные процедурного типа? Хм, лично мне не сложно и ручками написать @P <> nil, но это не важно... С этим понятно..

 Второй вопрос открыт: известны ли кому-нибудь способы, как узнать был ли убит объект, если он был убит НЕ FreeAndNil а банальным деструктором Free?


Сергей М.   (2007-10-09 17:31:00) [34]


> ачем нужна ф-ция Assign, если можно написать
> if p<>nil then ...
>


Встречный вопрос - зачем писать

if p<>nil then ...

если можно написать

if Assign ed(p) then ...

?

На первое время считай, что разницы никакой.


> узнать был ли убит объект


Если возникло исключение EAccessViolation или EInvalidPointer, то объект 100%-но "убит".
Вероятность же невозникновения одного из этих исключений при гарантированно "убитом" объекте ничтожно мала.


clickmaker   (2007-10-09 17:29:00) [35]

Assigned(P) corresponds to the test P<> nil for a pointer variable, and @P <> nil for a procedural variable (c) F1


> переменная-объект по-прежнему не nil

FreeAndNil()


Страницы:   1 2

Наверх

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