-
ggg (19.06.08 19:39) [0]У меня в программе некоторые объекты имеют счетчик использования. Сделано это для того, что бы они не были удалены до того, когда на них перестанут ссылаться другие объекты.
Сначала пробывал добавить следующий код в деструктор:
destructor TGraphicObject.Destroy;
begin
if UseCount > 0 then
begin
FMustBeFree := true;
Exit;
end;
...
Но практически сразу же получал AV.
Поэтому создал метод Free;
procedure TGraphicObject.Free;
begin
if Assigned(Self) then
if UseCount > 0 then
FMustBeFree := true
else
inherited; // или Destroy, не важно
end;
Пока вроде бы проблем не наблюдается, но как-то беспокойно на душе :)
Собственно вопросы:
1) Destroy в любом случае удаляет объект, даже если там стоит Exit и не вызывается inherited?
2) Метод Free не помечен как virtual, соответсвенно и мой метод не может быть отмечен как override. Безопасно ли использовать такой способ? Или правильней будет создать некий MyFreeMethod, где будет проверяться FUseCount и вызываться Free? -
Поросенок Винни-Пух © (19.06.08 20:04) [1]procedure TGraphicObject.Free;
begin
if Assigned(Self) then
гениально. -
Поросенок Винни-Пух © (19.06.08 20:05) [2]А оунер этого волшебного объекта в курсе что кто-то там что-то там считает?
:) -
Игорь Шевченко © (19.06.08 20:06) [3]тебе надо посмотреть, как работает TInterfacedObject._Release - оно так примерно и делает, если ссылок 0, то вызывает Destroy
Или переопределить метод FreeInstance -
Игорь Шевченко © (19.06.08 20:06) [4]Поросенок Винни-Пух © (19.06.08 20:04) [1]
> if Assigned(Self) then
>
> гениально.
Тебе никогда не встречался Self=nil ? -
Поросенок Винни-Пух © (19.06.08 22:30) [5]Мне интересно куда он там мог деться в первой же строчке собственного метода, что его проверяют на нил
-
Поросенок Винни-Пух © (19.06.08 22:34) [6]Сделано это для того, что бы они не были удалены до того, когда на них перестанут ссылаться другие объекты.
То есть есть самодельный механизм подсчета и зачем-то переделываются методы дестрой и фри.
А для чего? Для того, чтобы можно было в любой строчке собственного когда неглядя вызвать фри объекта, не опасаясь что он будет удален если на него есть ссылки?
А не логичнее ли вызывать фри по условию, если уж автору известно есть ссылки или нет их? -
Loginov Dmitry © (19.06.08 22:53) [7]> Мне интересно куда он там мог деться в первой же строчке
> собственного метода, что его проверяют на нил
var
g: TGraphicObject;
begin
g := nil;
g.Free;
end;
Что произойдет вg.Free
, еслиif Assigned(Self)
не делать? -
Поросенок Винни-Пух © (19.06.08 22:56) [8]ты во внутрь самого фри не попадешь при таком раскладе
-
Loginov Dmitry © (19.06.08 23:00) [9]> ты во внутрь самого фри не попадешь при таком раскладе
Free - это статический метод (фактически обычная процедура). Почему же я в нее не попаду? -
Anatoly Podgoretsky © (19.06.08 23:09) [10]> Loginov Dmitry (19.06.2008 22:53:07) [7]
А зачем его делать?
Советую взглянуть генофонд или прочитать справку. -
Поросенок Винни-Пух © (19.06.08 23:14) [11]Что произойдет в g.Free, если if Assigned(Self) не делать?
Произойдет то же самое, что происходит если делать if Assigned(Self)
g := nil;
g := T...Create();
g.Free; -
Поросенок Винни-Пух © (19.06.08 23:15) [12]Нагляднее так:
type
ttt = class
procedure test;
end;
procedure ttt.test;
begin
if Assigned(Self) then ShowMessage('yes') else ShowMessage('no');
end;
procedure TForm1.Button1Click(Sender: TObject);
var t : ttt;
begin
t := nil;
t := ttt.Create;
t.Free;
t.test;
end; -
Loginov Dmitry © (19.06.08 23:16) [13]> А зачем его делать?
У автора реализован собственный метод Free. В нем выполняется проверка if Assigned(Self). Что произойдет в g.Free (из [7]), если if Assigned(Self) (в TGraphicObject.Free) не делать? -
Eraser © (19.06.08 23:18) [14]> [0] ggg (19.06.08 19:39)
> if Assigned(Self) then
> if UseCount > 0 then
в данном коде смущает то, что большое количество вложенных условий делает код запутанным.
imho, уместнееif not Assigned(Self) then
Exit; -
Поросенок Винни-Пух © (19.06.08 23:20) [15]У автора реализован собственный метод Free. В нем выполняется проверка if Assigned(Self). Что произойдет в g.Free (из [7]), если if Assigned(Self) (в TGraphicObject.Free) не делать?
произойдет все то же самое если её делать. -
Loginov Dmitry © (19.06.08 23:24) [16]> imho, уместнее
> if not Assigned(Self) then
> Exit;
имхо, нагляднее так:procedure TGraphicObject.Free;
begin
if Assigned(Self) then
begin
if UseCount > 0 then
FMustBeFree := true
else
inherited; // или Destroy, не важно
end;
end;
Но у каждого будет свое имхо и спорить, имхо, бессмысленно. -
Loginov Dmitry © (19.06.08 23:26) [17]> произойдет все то же самое если её делать.
Для чего тогда, по Вашему, в TObject.Free() реализована такая же проверка? -
Поросенок Винни-Пух © (19.06.08 23:29) [18]я ж нарисовал пример в котором assigned рапортует "yes"
и типа после этого метод уверен, что можно что-то там делать. -
Loginov Dmitry © (19.06.08 23:55) [19]> я ж нарисовал пример в котором assigned рапортует "yes"
> и типа после этого метод уверен, что можно что-то там делать.
совать во Free() битые ссылки - ситуация ненормальная и естественно карается. А вот вызов TObject(nil).Free - это обычное дело, и без проверки на nil не обойтись.