Welcome

首页 / 软件开发 / Delphi / Delphi2009初体验 - 语言篇 - 智能指针(Smart Pointer)的实现(二)

Delphi2009初体验 - 语言篇 - 智能指针(Smart Pointer)的实现(二)2012-02-15 博客园 杨芹勍一、弊端

在此先要感谢网友装配脑袋的提醒,在我关于Delphi中实现智能指针的第一篇文章“Delphi2009初体验 - 语言篇 - 智能指针的实现”里,装配脑袋给我提出了这么个问题:

“管这个叫智能指针未免名不副实了一点,实际上class型的对象引用与指针的语义有跟大的不同。而C++的智能指针就是为了在语义上获得方便性的一种机制。 ”

后来我想了想,确实存在装配脑袋所表述的问题。在原来的代码中,我进行了如下约束:

IAutoPtr<T:class>=interface(IInterface)

我将T类型规定为必须为一个类类型(class型),如果使用TAutoPtr包囊class型的TObject,那么TAutoPtr只能算是一个“智能对象”,而不是“智能指针”。在此,我们把T: class的约束class去掉,此处就能传入非class型的类型了,当然也包括指针类型。

二、提出问题

然而,把约束: class去掉,会带来一些问题:

首先贴出原来的代码:

1 type
2 IAutoPtr<T: class> = interface(IInterface)
3 ["{BD098FDB-728D-4CAC-AE40-B12B8B556AD3}"]
4 function Get: T;
5 function Release: T;
6 procedure Reset(aObj: T);
7 end;
8
9 TAutoPtr<T: class> = class(TInterfacedObject, IAutoPtr<T>)
10 private
11fObj: T;
12 public
13class function New(aObj: T): IAutoPtr<T>;
14constructor Create(aObj: T); virtual;
15destructor Destroy; override;
16 function Get: T;
17 function Release: T;
18 procedure Reset(aObj: T);
19 end;
20
21 implementation
22
23 { TAutoPtr<T> }
24
25 constructor TAutoPtr<T>.Create(aObj: T);
26 begin
27 fObj := aObj;
28 end;
29
30 class function TAutoPtr<T>.New(aObj: T): IAutoPtr<T>;
31 begin
32 Result := TAutoPtr<T>.Create(aObj) as IAutoPtr<T>; // 注意:此处如果不加as IAutoPtr<T>,程序运行时会报错,第一次我没有加as IAutoPtr<T>程序运行一切正常,到后面就不行了,不知道是为什么
33 end;
34
35 function TAutoPtr<T>.Release: T;
36 begin
37 Result := fObj;
38 fObj := nil;
39 end;
40
41 procedure TAutoPtr<T>.Reset(aObj: T);
42 begin
43 if aObj <> fObj then
44 begin
45 FreeAndNil(fObj);
46 fObj := aObj;
47 end;
48 end;
49
50 destructor TAutoPtr<T>.Destroy;
51 begin
52 if fObj <> nil then
53 begin
54 FreeAndNil(fObj);
55 end;
56
57 inherited;
58 end;
59
60 function TAutoPtr<T>.Get: T;
61 begin
62 Result := fObj;
63 end;
1、在Release方法内的“fObj := nil”,编译器将不支持,因为fObj为T类型,T可以为值类型,值类型赋值为nil是不允许的。

2、在Reset(aObj: T)方法内的“aObj <> fObj”,编译器将不支持,虽然aObj和fObj都为T类型,但是泛型T为任意类型,并不是任何类型都支持“<>”比较运算符的。

3、Destroy方法内的“if fObj = nil then”不被支持,原因和第一点一样。

4、Destroy方法内的“FreeAndNil(fObj)”不被支持,因为T可能是值类型,原因和第一点一样。