{******************************************************
*
* 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)的实现
最新推荐文章于 2020-11-19 23:24:16 发布