You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi接口自动引用计数:对象内存管理相关疑问

问题描述

给定以下Pascal代码:

接口与实现类型

IMyBuilderIntf = interface
  function Build(): String;
end;

//...

TMyConcreteType = class(TInterfacedObject, IMyBuilderIntf)
  //...
  function Build(): String;
end;

接收接口的函数

function MyFunctionUsingInterface(AParam: IMyBuilderIntf): Boolean;
begin
  //...
  AParam.Build();
  //...
end;

客户端调用代码

function EntryPoint(): Integer;
var
  concreteBldr: TMyConcreteType;
begin
  // 调用TMyConcreteType中声明的特定方法
  MyFunctionUsingInterface(concreteBldr); // <<<<<<<<<
end;

请问:

  1. 存储在concreteBldr中的对象内存会被自动管理吗?
  2. 是否所有通过接口访问的对象都会被自动管理?
  3. 该自动管理行为是否依赖对象之前声明的类型(具体或抽象)?

解答

1. concreteBldr中的对象内存不会被自动管理

concreteBldr是具体类类型变量,并非接口类型。当你把它传递给MyFunctionUsingInterface时,会隐式生成一个临时接口引用,但这个临时引用在函数执行结束后就会被释放。而原始的concreteBldr作为类类型变量,不会触发Delphi的引用计数机制——Delphi的自动内存管理仅对接口类型变量生效,类类型变量必须手动调用Free释放内存,否则会造成内存泄漏。

2. 并非所有通过接口访问的对象都会被自动管理

只有满足两个条件才会触发自动内存管理:一是对象的类继承自TInterfacedObject(或其他正确实现IInterface引用计数逻辑的类),二是通过接口类型变量持有对象引用。如果对象的类没有实现_AddRef、_Release这类引用计数方法,哪怕通过接口访问,也不会自动管理内存。

3. 自动管理行为不依赖对象声明的类型(具体/抽象)

该行为只取决于两个核心条件:

  • 对象的类是否正确实现了IInterface的引用计数方法(通常继承TInterfacedObject即可自带实现);
  • 是否通过接口类型变量持有对象的引用。

无论对象是具体类还是抽象类,只要满足上述两个条件,就能触发自动内存管理;反之,哪怕是具体类,用类类型变量持有也不会自动释放。

内容的提问来源于stack exchange,提问作者Arthur Araujo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:55:59