среда, 29 июня 2016 г.

Задачка

Может ли класс-деструктор (или finalization-секция модуля) выполниться раньше обычного деструктора? Если может, то при каком условии?

6 коммент.:

Alex Werewolf комментирует...

Динамические пакеты? UnloadPackage?

Николай Зверев комментирует...

Не совсем. UnloadPackage дёргает FinalizePackage и сразу выгружает библиотеку из памяти (FreeLibrary). После этого (если я правильно всё понимаю) деструктор некоего объекта уже выгруженной библиотеки дёрнуть просто не получится.
Т.е. да, finalization/class-destructor выполнится раньше деструктора, но деструктор вообще не отработает - будет утечка памяти.

Я про другой случай, всё в рамках single-exe, и деструктор вызывается корректно. Подскажу: такое можно получить, когда необходимо сигнализировать об аварийном завершении приложения.

Alex Werewolf комментирует...

Согласен, деструктор не отработает, т.к. VMT класса будет уже не доступна, а компилятор заставляет туда лезть даже когда деструктор не переопределен =( Можно конечно пропатчить указатель на класс инстанса, но это уже другая история =)

а так, с подсказкой ;-) очевидно следующее:
program ConsHalt;
{$APPTYPE CONSOLE}
{$I-}

type
TMyClass = class
public
class destructor CD;
destructor Destroy; override;
end;

destructor TMyClass.Destroy;
begin
WriteLn('instance destructor');
ReadLn;
inherited;
end;

class destructor TMyClass.CD;
begin
WriteLn('class destructor');
end;

procedure ExitP();
var
Obj: TMyClass;
begin
Obj := TMyClass.Create;
Obj.Free;
end;

begin
ExitProcessProc := ExitP;
Halt;
end.

выдает
class destructor
instance destructor

Николай Зверев комментирует...

Примерно так, да.
Я на эту проблему наткнулся, когда делал Halt из OnCreate датамодуля (или формы - не важно, один эффект). Т.е. вот вроде бы нормальная ситуация - создаю датамодуль (ещё до создания каких-либо форм), он делает проверки, если что-то не устроило - Halt(X). Ан нет, так нельзя для VCL-приложения. Надо делать ExitCode := X и дальше Application.Terminate + Exit
Ну или Abort/своё_исключение с обработкой в dpr-файле.

Alex Werewolf комментирует...

ExitProcess(X) в помощь, если не нужно ничего "убирать" за собой ;-)

Николай Зверев комментирует...

Так ExitProcess как раз и дёргается Halt'ом и приводит к эффекту в задачке.

Отправить комментарий

.

.