2014-06-16 67 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它在我運行它時起作用。你爲什麼認爲這是錯的?請讓我們知道,而不是如此神祕。如果出現問題,那麼我想明白這一點。 –

相關問題