![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
FreeAndNil, пожалуйста, еще раз.
Наивный © (2012-08-11 11:20:00)XE2, W7:
type
TTestClass = class(TObject)
private
Mem:Pointer;
public
constructor Create;
procedure Free;
end;
constructor TTestClass.Create;
begin
inherited Create;
GetMem(Mem,1024);
end;
procedure TTestClass.Free;
begin
FreeMem(Mem);
inherited Free;
end;
var
Obj:TTestClass;
begin
Obj:=TTestClass.Create;
FreeAndNil(Obj); // !?
end.
Почему не происходит вызов TTestClass.Free
или как сделать правильно?
Германн (2012-08-12 02:25:00) [1]
> О, а тут еще и
> 1
>
> class constructor, class destructor
А вот это самое главное в данном вопросе. Тут уже ясно сказано где создавать и где уничтожать.
Наивный (2012-08-11 17:52:00) [2]> turbouser © (11.08.12 16:41) [13]
>> А виртуальный/динамический - синонимы или есть различия?
>F1 -> Generally, use virtual methods.-> Ok.
О, а тут еще иclass constructor, class destructor- буду осваивать.
turbouser (2012-08-11 16:41:00) [3]
> Наивный (11.08.12 16:36) [11]
>
> [9], [10] , да понемногу ситуация проясняется, спасибо.
>
> А виртуальный/динамический - синонимы или есть различия?
>
>
F1
turbouser (2012-08-11 16:40:00) [4]
> Наивный (11.08.12 16:36) [11]
> Нет-нет
destroy
:=nil
etc
Наивный (2012-08-11 16:36:00) [5][9], [10], да понемногу ситуация проясняется, спасибо.
А виртуальный/динамический - синонимы или есть различия?
[9]
> А уже из TObject.Free будет вызван правильный деструктор, который виртуальный.
Значит, правильно - не использовать (совсем?) в своих классах Free, а переопределить деструктор?
[8]
> Но если параноидально хочется удостовериться в освобождении ресурсов
Нет-нет, но все-таки, что подразумевает >освобождай вручную?
Юрий Зотов (2012-08-11 16:00:00) [6]> Наивный (11.08.12 14:33) [7]
> у меня, наверное, пробел в понимании ООП
Есть немного. Вам нужно понять разницу между статическими и виртуальными/динамическими методами.
> поскольку подумал, что Temp.Free; запустит вначале мой TTestClass.Free
Так было бы, если бы метод TObject.Free был виртуальным (или динамическим). А он статический, поэтому процедура Free вызывает TObject.Free, а не Ваш.
Давайте будем жрать! (2012-08-11 15:43:00) [7]
> подумал, что Temp.Free; запустит вначале мой TTestClass.
> Free
Она о TTestClass.Free ничего не знает. Free — метод статический (и это хорошо), так что при вызове TObject(Obj).Free будет вызван Free именно из TObject. А уже из TObject.Free будет вызван правильный деструктор, который виртуальный.
turbouser (2012-08-11 14:44:00) [8]
> Наивный (11.08.12 14:33) [7]
Нет повода для сомнений.
Но если параноидально хочется удостовериться в освобождении ресурсов - освобождай вручную, никто не запрещает.
Наивный (2012-08-11 14:33:00) [9]> AV © (11.08.12 13:29) [6]
Да, я это видел, но у меня, наверное, пробел в понимании ООП, поскольку подумал, чтоTemp.Free;запустит вначале мойTTestClass.Free;в котором и будет дополнительная обработка ситуации когда Self=nil, - а уж потом я запущуinherited Free;, "фишка" которого в маскировании проблемы или вызове деструктора.
Думаю, если бы FreeAndNil была такой:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp:=InterlockedExchangePointer(Pointer(Obj),nil);
if Temp<>nil then Temp.Destroy // !
else // Ахтунг! Вы разрушаете вакуум!!!
end;
понимание и ценность ее использования была бы выше.
> turbouser © (11.08.12 12:23) [5]
>Free.
>Много раз уже обсуждалось.
Вот поэтому я и засомневался, но, спасибо, ненадолго. (теперь я сомневаюсь еще больше :))
AV (2012-08-11 13:29:00) [10]procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
turbouser (2012-08-11 12:23:00) [11]
> это к FreeAndNil(Obj);
Free.
Много раз уже обсуждалось.
Наивный (2012-08-11 12:17:00) [12]> Зачем такие извращения?
это кFreeAndNil(Obj);
или кdestructor Destroy; override;
Наивный (2012-08-11 12:15:00) [13]Спасибо.
Получается, нужно освобождать ресурсы в своем перекрытом Destroy.?
Но тогда зачем же красноречивая процедура Free и рекомендации даже ее не использовать в коде непосредственно?
turbouser (2012-08-11 12:08:00) [14]Зачем такие извращения?
sniknik (2012-08-11 11:46:00) [15]> Почему не происходит вызов TTestClass.Free
потому как это простая, на виртуальная и т.д. процедура.
> или как сделать правильно?
перекрывать деструктор
destructor Destroy; override;