[fpc-pascal] Management operators question
Ryan Joseph
ryan at thealchemistguild.com
Sat May 26 03:22:45 CEST 2018
> On May 25, 2018, at 7:03 PM, Maciej Izak <hnb.code at gmail.com> wrote:
>
> all is balanced :) you forgot to handle operator :
>
> class operator Copy(constref src: TDynArray<T>; var dest: TDynArray<T>);
>
> and
>
> class operator AddRef(var a: TDynArray<T>);
>
> for the line from example "d := TIntArray.Create([1, 2, 3]);" the "Copy" operator is executed (you need to check when which operator is used - this is the best way to learn, on the beginning it may looks a bit complicated): so for each AddRef, Copy and Initialization the Finalization operator is executed.
>
I expanded the example but there’s still one thing I don’t get. How can it be that Initialize/Finalize are called in a pair then push is called directly after? I expected Finalize to be the final call before the the object is out of scope and not usable anymore. If I was keeping reference counts I would already be at 0 when the first push call was made.
init 00007FFEEFBFF828
dealloc 00007FFEEFBFF828
push 1 to 00007FFEEFBFF828 <—— here’s where I’m confused
type
generic TDynArray<T> = record
private type TDynArrayTable = array[0..0] of T;
private type TDynArrayTablePtr = ^TDynArrayTable;
private
table: TDynArrayTablePtr;
public
constructor Create (values: array of T);
procedure Push(value: T);
class operator Finalize(var a: TDynArray);
class operator Initialize(var a: TDynArray);
class operator AddRef(var a: TDynArray);
class operator Copy(constref aSrc: TDynArray; var aDst: TDynArray);
end;
constructor TDynArray.Create (values: array of T);
var
value: T;
begin
for value in values do
Push(value);
end;
class operator TDynArray.AddRef(var a: TDynArray);
begin
writeln('addref');
end;
class operator TDynArray.Copy(constref aSrc: TDynArray; var aDst: TDynArray);
begin
writeln('copy ', HexStr(@aSrc), ' to ', HexStr(@aDst));
end;
class operator TDynArray.Initialize(var a: TDynArray);
begin
writeln('init ', HexStr(@a));
a.table := nil;
end;
class operator TDynArray.Finalize(var a: TDynArray);
begin
if a.table <> nil then
begin
FreeMem(a.table);
writeln('free');
a.table := nil;
end;
writeln('dealloc ', HexStr(@a));
end;
procedure TDynArray.Push(value: T);
begin
if table = nil then
table := GetMem(0);
writeln('push ', value, ' to ', HexStr(@self)); // grow array etc...
end;
procedure TestDynArray;
type
TIntArray = specialize TDynArray<Integer>;
var
d: TIntArray;
begin
d := TIntArray.Create([1, 2, 3]);
d.Push(100);
end;
init 00007FFEEFBFF7C0
init 00007FFEEFBFF828
dealloc 00007FFEEFBFF828
push 1 to 00007FFEEFBFF828
push 2 to 00007FFEEFBFF828
push 3 to 00007FFEEFBFF828
copy 00007FFEEFBFF828 to 00007FFEEFBFF7C0
push 100 to 00007FFEEFBFF7C0
free
dealloc 00007FFEEFBFF828
free
dealloc 00007FFEEFBFF7C0
Regards,
Ryan Joseph
More information about the fpc-pascal
mailing list