{******************************************************
*
* Delphi Smart Pointer class
* AutoPtr
* Version 0.2 beta
* Yang Qinqing @ http://www.cnblogs.com/felixyeou
*
*******************************************************}
unitAutoPtr;
interface
uses
SysUtils,
TypInfo;
type
IAutoPtr<T>=interface
['{86DB82D6-9A32-4A6A-9191-2E0DFE083C38}']
functionGet:T;
functionRelease:T;
procedureReset(aObj:T);
end;
TAutoPtr<T>=class(TInterfacedObject,IAutoPtr<T>)
private
fObj:T;
fTypeInfo:PTypeInfo;
procedureFreeObj;
public
classfunctionNew(aObj:T):IAutoPtr<T>;overload;
classfunctionNew:IAutoPtr<T>;overload;
constructorCreate(aObj:T);virtual;
destructorDestroy;override;
functionGet:T;
functionRelease:T;
procedureReset(aObj:T);
end;
implementation
{TAutoPtr<T>}
constructorTAutoPtr<T>.Create(aObj:T);
begin
fObj:=aObj;
//獲取泛型的類型
fTypeInfo:=TypeInfo(T);
end;
classfunctionTAutoPtr<T>.New(aObj:T):IAutoPtr<T>;
begin
Result:=TAutoPtr<T>.Create(aObj)asIAutoPtr<T>;
end;
functionTAutoPtr<T>.Release:T;
begin
Result:=fObj;
//fObj:=nil
Integer((@fObj)^):=0;
end;
procedureTAutoPtr<T>.Reset(aObj:T);
begin
//aObj<>fObjthen
ifInteger((@aObj)^)<>Integer((@fObj)^)then
begin
FreeObj;
fObj:=aObj;
end;
end;
destructorTAutoPtr<T>.Destroy;
begin
//iffObj=nilthen..
ifInteger((@fObj)^)<>0then
FreeObj;
fTypeInfo:=nil;
inherited;
end;
procedureTAutoPtr<T>.FreeObj;
begin
//此處如果TypeInfo爲空,則說明T爲Pointer
//此處只要簡單的釋放內存即可
iffTypeInfo=nilthen
//FreeMem(Pointer((@fObj)^))
//此處應該調用Dispose,因爲Dispose內部已經實現FreeMem:
//PUSH EAX
//CALL _Finalize
//POP EAX
//CALL _FreeMem
Dispose(Pointer((@fObj)^))
else
begin
casefTypeInfo.Kindof
tkClass:
//調用Object.Free,進而調用DestructorDispose(virtual)方法
//實現在對象樹上的遍歷釋放
TObject((@fObj)^).Free;
tkArray,tkDynArray:
//數組和動態數組無需釋放
end;
end;
//fobj:=nil;
Integer((@fObj)^):=0;
end;
functionTAutoPtr<T>.Get:T;
begin
Result:=fObj;
end;
classfunctionTAutoPtr<T>.New:IAutoPtr<T>;
var
typInfo:PTypeInfo;
obj:TObject;
objNew:T;
begin
typInfo:=TypeInfo(T);
//在此處只能創建class型的指針,不能創建無類型指針
//因爲指針在Delphi中有兩種初始化方式
//1、GetMem(p,100);
//2、New(p);
if(typInfo<>nil)and(typInfo.Kind=tkClass)then
begin
//獲取T的類型並調用默認構造函數創建對象
obj:=GetTypeData(typInfo).ClassType.Create;
//使用以下方法強制轉換
objNew:=T((@obj)^);
Exit(New(objNew));
end;
raiseException.Create('只能構造class型的對象。');
end;
智能指針(Smart Pointer)的實現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.