2014-06-16 65 views
1

下面的代码不能编译,但是有可能吗?可以使用静态方法实现接口吗?

IDefaultHelp = interface 
    ['{6997FC42-7481-4CDA-940A-0351071266C7}'] 
    function GetTemplate: TXMLDocument; 

    end; 

    TDefaultHelp = class(TInterfacedObject, INodeHelp) 
    class function GetTemplate: TXMLDocument; static; <<-- error 
    end; 

我不想实例化实现对象。

有没有一种方法来实现接口,而不必Create一个实际的类?

+1

如果没有实例,谁去跟踪引用计数吗? –

+0

当然,你可能不想引用计数。因此,如果您正在寻找静态方法的接口,请查看默认比较器接口在泛型单元中的实现方式。用函数指针的记录按vtable的顺序排列。 –

+0

是的,这对于非refcounting接口是可能的;你仍然需要一个实例(没有没有实例的接口),但是你可以声明实例为一个常量,所以你不需要在运行时创建一个实例。 – kludg

回答

1

我必须承认,我真的没有看到需要避免实例化一个实例。现在,您不能使用静态类方法来实现接口。如果您愿意,您可以通过委派静态类方法来实现一个接口。

我不想实例化实现对象。

所以,把你的问题,以实现接口,而无需实例化对象的愿望,你可以用一个恒定的虚函数表,从Generics.Defaults单元的比较器接口的方式实现。

例如:

unit Unit1; 

interface 

uses 
    Xml.XMLDoc; 

type 
    IDefaultHelp = interface 
    ['{6997FC42-7481-4CDA-940A-0351071266C7}'] 
    function GetTemplate: IXMLDocument; 
    end; 

function GetDefaultHelp: IDefaultHelp; 

implementation 

function NopAddref(inst: Pointer): Integer; stdcall; 
begin 
    Result := -1; 
end; 

function NopRelease(inst: Pointer): Integer; stdcall; 
begin 
    Result := -1; 
end; 

function NopQueryInterface(inst: Pointer; const IID: TGUID; out Obj): HResult; 
    stdcall; 
begin 
    Result := E_NOINTERFACE; 
end; 

function GetTemplate(inst: Pointer): IXMLDocument; 
begin 
    Result := TXMLDocument.Create(nil); 
end; 

const 
    DefaultHelp_Vtable: array[0..3] of Pointer = 
    (
    @NopQueryInterface, 
    @NopAddref, 
    @NopRelease, 
    @GetTemplate 
); 
    DefaultHelp_Instance: Pointer = @DefaultHelp_Vtable; 

function GetDefaultHelp: IDefaultHelp; 
begin 
    Result := IDefaultHelp(@DefaultHelp_Instance); 
end; 

end. 
+0

@ user246408,它在System.Generics中工作得很好,为什么它不能在这里工作? – Johan

+0

意味着System.Generics没有像上面那样的bug;) – kludg

+0

@ user246408它在我运行它时起作用。你为什么认为这是错的?请让我们知道,而不是如此神秘。如果出现问题,那么我想明白这一点。 –

相关问题