Счетчик ссылок Delphi для подклассов

Скажите, что у меня есть такая ситуация:

ITest = interface
 procedure somethingHere();
end;

TImpl = class(TInterfacedObject, ITest)
 procedure somethingHere();
end;

TImplSub = class(TImpl)

end;

Учитывая код выше, я могу использовать этот тип кода без утечки памяти, если я не использую оператор try-finally:

var a: ITest;
begin
 a := TImpl.Create;
end;

Это то же самое для подкласса?

var a: ITest;
begin
 a := TImplSub.Create;
end;

Я думаю, что поскольку TImplSub является подклассом TImpl, TImplSub наследует TInterfacedObject и ITest от отца. Вызывается ли вышеуказанный код?

Это может быть не связано, но как я могу проверить, не выше ли утечка кода?

Ответ 1

Счётчик ссылок для ссылок на интерфейс запускается с помощью методов _AddRef и _Release, которые в этом случае реализованы в TInterfacedObject. Ваш подкласс наследует это поведение подсчета ссылок.

Вы можете использовать, на самом деле, ссылки на интерфейс, чтобы хранить экземпляр объекта подкласса, как вы его закодировали. (Не использовать ссылку на интерфейс для хранения экземпляров ссылочных экземпляров ссылок, нарушает механизм подсчета ссылок)

Следующий код не протекает и не требует блока try...finally, поскольку уничтожение происходит автоматически.

var a: ITest;
begin
 a := TImplSub.Create;
end;

Чтобы проверить утечки памяти в компиляторе Windows, вы можете использовать ReportMemoryLeaksOnShutdown

begin
  ReportMemoryLeaksOnShutdown := true;
  ...
end.

Другой способ проверить, уничтожен ли объект, когда вы исследуете конкретное поведение, - это переопределить деструктор и установить там точку останова.

Ответ 2

Благодаря комментариям (пользователь @nil) мне удалось сделать такой тест

type
 ITest = interface
   procedure test;
 end;

 TProva = class(TInterfacedObject, ITest)
   procedure test;
 end;

 TProvaSub = class(TProva)
   procedure testDue;
 end;

И затем, если вы попытаетесь запустить этот код (в режиме отладки с F9):

procedure TForm1.Button1Click(Sender: TObject);
var a: ITest;
begin    
 a := TProvaSub.Create;
 a.test;    
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown:=DebugHook<>0;
end;

Когда я закрываю форму, у меня нет отчета об утечке.


Мое заключение: TProvaSub имеет кусок TProva внутри себя (поскольку он является подклассом), и поэтому он наследует _AddRef и _Release. Таким образом, код хорош и не течет!