1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
program tmoperator7;
{$MODE DELPHI}
type
TFoo = record
private
class operator Initialize(var aFoo: TFoo);
class operator Finalize(var aFoo: TFoo);
public
I: Integer;
public class var
InitializeCount: Integer;
FinalizeCount: Integer;
end;
TFooObj = object
public
F: TFoo;
end;
TFooArray = array of TFoo;
TFooObjArray = array of TFooObj;
{ TFoo }
class operator TFoo.Initialize(var aFoo: TFoo);
begin
Inc(InitializeCount);
if aFoo.I <> 0 then // for dyn array and old obj
Halt(1);
WriteLn('TFoo.Initialize');
aFoo.I := 1;
end;
class operator TFoo.Finalize(var aFoo: TFoo);
begin
Inc(FinalizeCount);
if aFoo.I <> 2 then
Halt(2);
WriteLn('TFoo.Finalize');
end;
procedure CheckFooInit(var AValue: Integer; const AExpectedInitializeCount: Integer);
begin
if AValue <> 1 then
Halt(3);
AValue := 2;
if TFoo.InitializeCount <> AExpectedInitializeCount then
Halt(4);
end;
procedure CheckFooFini(const AExpectedFinalizeCount: Integer);
begin
if TFoo.FinalizeCount <> AExpectedFinalizeCount then
Halt(5);
end;
procedure FooTest;
var
Foos: TFooArray;
FoosObj: TFooObjArray;
begin
WriteLn('=== DynArray of Records ===');
SetLength(Foos, 1);
CheckFooInit(Foos[0].I, 1);
SetLength(Foos, 2);
CheckFooInit(Foos[1].I, 2);
SetLength(Foos, 1);
CheckFooFini(1);
SetLength(Foos, 2);
CheckFooInit(Foos[1].I, 3);
Foos := nil;
CheckFooFini(3);
WriteLn('=== DynArray of Objects ===');
TFoo.InitializeCount := 0;
TFoo.FinalizeCount := 0;
SetLength(FoosObj, 1);
CheckFooInit(FoosObj[0].F.I, 1);
SetLength(FoosObj, 2);
CheckFooInit(FoosObj[1].F.I, 2);
SetLength(FoosObj, 1);
CheckFooFini(1);
SetLength(FoosObj, 2);
CheckFooInit(FoosObj[1].F.I, 3);
FoosObj := nil;
CheckFooFini(3);
end;
begin
FooTest;
end.
|