將類層次結構的祖先從TObject更改爲TInterfacedObject是否有任何副作用,以便我可以在繼承鏈下面實現接口?在Delphi中將接口引入到現有的類層次結構中
我在Delphi中編寫了幾年,但從未遇到過接口。我習慣於用其他語言來使用它們。現在我又參與了一個Delphi項目,我想開始利用它們,但我知道它們的工作方式與Java或C#中的有所不同。
將類層次結構的祖先從TObject更改爲TInterfacedObject是否有任何副作用,以便我可以在繼承鏈下面實現接口?在Delphi中將接口引入到現有的類層次結構中
我在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;
在大多數情況下,對象在單個函數中創建和銷燬。我主要擔心的是計數引用是否會干擾手動內存管理。它是一個龐大的代碼庫,只有很少的單元測試,因此我計劃逐步替換引用。 – 2010-10-28 16:43:13
@codeelegance:是的,接口計數取代手動內存管理。您可以在任何給定的對象上使用其中一種,但不能同時使用這兩種。 – 2010-10-28 16:48:35
@Mason所以只要我沒有對象引用和指向同一對象的接口引用,我應該沒問題? – 2010-10-28 16:54:41