将类层次结构的祖先从 TObject 更改为 TInterfacedObject 是否有任何副作用,以便我可以在继承链的下游实现接口?
我已经在 Delphi 中编程了几年,但从未遇到过接口。我习惯于在其他语言中使用它们。现在我再次参与了一个 Delphi 项目,我想开始利用它们,但我知道它们的工作方式与 Java 或 C# 中的不同。
将类层次结构的祖先从 TObject 更改为 TInterfacedObject 是否有任何副作用,以便我可以在继承链的下游实现接口?
我已经在 Delphi 中编程了几年,但从未遇到过接口。我习惯于在其他语言中使用它们。现在我再次参与了一个 Delphi 项目,我想开始利用它们,但我知道它们的工作方式与 Java 或 C# 中的不同。
如果您已经有使用该类的现有代码,则可能必须修改其中的很多内容以保留对接口而不是对象实例的引用。接口被引用计数并自动释放,因此,任何对实现器实例的引用都将成为无效指针。
只要您从层次结构顶部(底部?)的下面的类继承,这将正常工作。这段代码确保你的新类不会释放自己——就像 TInterfaceObject 的默认行为一样——你可能已经自己释放了它们并希望保留它。这个活动实际上正是 VCL 中的 TComponent 所做的——它支持接口但不计入引用。
type
TYourAncestor = class( TInterfacedObject )
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
implementation
function TYourAncestor.QueryInterface(const IID: TGUID; out Obj): HResult;
const
E_NOINTERFACE = HResult($80004002);
begin
if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;
end;
function TYourAncestor._AddRef: Integer;
begin
Result := -1 // -1 indicates no reference counting is taking place
end;
function TYourAncestor._Release: Integer;
begin
Result := -1 // -1 indicates no reference counting is taking place
end;
除了实例大小中的一些额外字节之外,没有。这可能是最好的方法。