您的位置:首页 > 编程语言 > Delphi

Delphi泛型应用示例之一:接口化指针

2015-02-27 10:47 218 查看


接口的引用计数特性可以让我们方便地创建一个接口实例,它可以到处使用而无需手动释放内存。但是假如我们这个接口里面有很多数据项那就麻烦多了,得针对每个数据项分别写出其Get和Set方法,接口要写一遍,类还要写一遍。

举个例子,我们想把这个记录类型用接口的方式实现:

TRecord_Test = record

Data1: string;

Data2: Integer;

Data3: Double;

end;

通常的方法是这样的:

type

TInterface_Test = interface

function GetData1: string;

function GetData2: Integer;

function GetData3: Double;

procedure SetData1(const Value: string);

procedure SetData2(const Value: Integer);

procedure SetData3(const Value: Double);

property Data1: string read GetData1 write SetData1;

property Data2: Integer read GetData2 write SetData2;

property Data3: Double read GetData3 write SetData3;

end;

TClass_Test = class(TInterfacedObject, TInterface_Test)

private

FData2: Integer;

FData3: Double;

FData1: string;

function GetData1: string;

function GetData2: Integer;

function GetData3: Double;

procedure SetData1(const Value: string);

procedure SetData2(const Value: Integer);

procedure SetData3(const Value: Double);

public

property Data1: string read GetData1 write SetData1;

property Data2: Integer read GetData2 write SetData2;

property Data3: Double read GetData3 write SetData3;

end;

implementation

{ TClass_Test }

function TClass_Test.GetData1: string;

begin

Result := FData1;

end;

function TClass_Test.GetData2: Integer;

begin

Result := FData2;

end;

function TClass_Test.GetData3: Double;

begin

Result := FData3;

end;

procedure TClass_Test.SetData1(const Value: string);

begin

FData1 := Value;

end;

procedure TClass_Test.SetData2(const Value: Integer);

begin

FData2 := Value;

end;

procedure TClass_Test.SetData3(const Value: Double);

begin

FData3 := Value;

end;

上面的代码是不是看得人吐血?要是有多个类似的记录,恐怕大家宁愿到处维护指针了。

不要紧,我们有万能的泛型。请看下述代码:

unit BambooInterfacedPointer;

interface

type

TValuePointer<T> = packed record

PValue: ^T;

end;

IBambooInterfacedPointer<T> = interface

function Instance: TValuePointer<T>;

end;

TBambooInterfacedPointer<T> = class(TInterfacedObject, IBambooInterfacedPointer<T>)

strict private

FValuePointer: ^T;

private

function Instance: TValuePointer<T>; inline;

public

constructor Create;

destructor Destroy; override;

end;

implementation

{ TBambooInterfacedPointer<T> }

constructor TBambooInterfacedPointer<T>.Create;

begin

inherited Create;

New(FValuePointer);

System.FillChar(FValuePointer^, SizeOf(T), 0);

end;

destructor TBambooInterfacedPointer<T>.Destroy;

begin

Dispose(FValuePointer);

inherited Destroy;

end;

function TBambooInterfacedPointer<T>.Instance: TValuePointer<T>;

begin

Result.PValue := FValuePointer;

end;

end.

说明一下,之所以要定义

type

TValuePointer<T> = packed record

PValue: ^T;

end;

这么一个东西,是因为在泛型接口里面不允许使用如下写法

IBambooInterfacedPointer<T> = interface

function Instance: ^T;

end;

所以定义了一个记录类型来作为过渡。

最后,则是我写的这个接口化指针的应用实例:

type

TRecord_Test = record

Data1: string;

Data2: Integer;

Data3: Double;

end;

var

aInterfacedPointer: IBambooInterfacedPointer<TRecord_Test>;

begin

aInterfacedPointer := TBambooInterfacedPointer<TRecord_Test>.Create;

with aInterfacedPointer.Instance.PValue^ do

begin

Data1 := '123';

Data2 := 456;

Data3 := 7.89;

end;

end;

是不是很方便啊 ? 重要的是 , 所有的数据类型都可以这么干 !


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: