智能指针(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;

原创粉丝点击