假设我有一个接口和实现该接口的具体类型,例如:
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
// Operates with specific functions declared and defined in TMyConcreteType.
MyFunctionUsingInterface(concreteBldr); // <<<<<<<
end;
存储在
concreteBldr
中的对象是否有内存管理? 通过接口访问的任何对象都会自动管理,并且此行为独立于之前声明的类型(具体或抽象)?
所示代码具有潜在危险,具体取决于
EntryPoint()
的其余部分的外观。
因为
concreteBldr
被声明为它的实现类类型,而不是它的接口类型,那么最初它的引用计数将为0,然后当传递给MyFunctionUsingInterface()
时它会增加到1(因为参数不是const
) ,然后当 MyFunctionUsingInterface()
退出时降至 0,从而立即释放对象。 如果随后尝试继续访问 concreteBldr
,代码将出现 未定义的行为 并且可能会崩溃。
要缓解这种情况,请设置参数
const
,或将 concreteBldr
的类型更改为 IMyBuilderIntf
。