智能指针(Smart Pointer)的实现

{******************************************************
*
* 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;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值