智能指针(Smart Pointer)的实现
来源:互联网 发布:weui.min.js cdn 编辑:程序博客网 时间:2024/05/21 14:01
{******************************************************** Delphi Smart Pointer class* AutoPtr* Version 0.2 beta* Yang Qinqing @ http://www.cnblogs.com/felixyeou********************************************************}unitAutoPtr;interfaceuses 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;