有結果可以看到,代碼中沒有釋放testInter指向的對象,對象由後台釋放了。如果將1*處改為testInter: TTestInterface;則結果如下,我們將看到如果不聲明為接口,即使創建同一個對象,Delphi是不會自動釋放對象的。
在此,我們利用了接口的自動管理功能,它自己維護著一個引用計數,當引用計數為0時接口自己會調用析構函數。關於Delphi接口的一些概念以及為什麼後台會自動釋放接口,可以參考以下兩篇文章,在此不做多余敘述。
1、Delphi 的接口機制淺探http://www.d99net.Net/article.ASP?id=206
2、淺談引用計數http://www.moon-soft.com/doc/13056.htm
四、Delphi中智能指針的實現
有了以上經驗,我們就可以實現我們的智能指針了!
首先,我們要創建一個繼承於TInterfacedObject的對象,在構造函數中傳入要管理的堆對象的引用,在析構函數裡FreeAndNil這個堆對象的引用。代碼如下:
unit ClassicalAutoPtr;
interface
uses
SysUtils;
type
TClassicalAutoPtr = class(TInterfacedObject)
private
fObj: TObject;
public
constructor Create(aObj: TObject); virtual;
destructor Destroy; override;
class function New(aObj: TObject): IInterface;
end;
implementation
{ TClassicalAutoPtr }
constructor TClassicalAutoPtr.Create(aObj: TObject);
begin
fObj := aObj;
end;
destructor TClassicalAutoPtr.Destroy;
begin
// 智能指針在方法退出時銷毀,同時銷毀所管理的堆對象
FreeAndNil(fObj);
inherited;
end;
class function TClassicalAutoPtr.New(aObj: TObject): IInterface;
begin
// 外部必須使用此方法創建智能指針
// 因為此方法會暴露給外部一個接口
// 後台碰到接口後會自動調用接口的析構函數
Result := TClassicalAutoPtr.Create(aObj);
end;
end.