Delphi - TList smart pointers and generics

I have an implementation of smart pointers and I tried to implement it on a generic TList.

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Generics.Collections;


type
  ISmartPointer<T> = reference to function: T;

  TSmartPointer<T: class, constructor> = class(TInterfacedObject, ISmartPointer<T>)
  private
    FValue: T;
    FName: string;
  public
    constructor Create; overload;
    constructor Create(AValue: T); overload;
    destructor Destroy; override;
    function Invoke: T;

    property Name: string read FName write FName;
  end;

  TTest = class
    FString: String;
  public
   property MyStrign: String read FString write FString;
  end;

{ TSmartPointer<T> }

constructor TSmartPointer<T>.Create;
begin
  inherited;

  FValue := T.Create;
end;

constructor TSmartPointer<T>.Create(AValue: T);
begin
  inherited Create;
  if AValue = nil then
    FValue := T.Create
  else
    FValue := AValue;
end;

destructor TSmartPointer<T>.Destroy;
begin
  if Assigned(FValue) then
    FValue.Free;

  inherited;
end;

function TSmartPointer<T>.Invoke: T;
begin
  Result := FValue;
end;

function TestSMP():ISmartPointer<TList<TTest>>;
var lTTest: ISmartPointer<TTest>;
    i: Integer;
begin
 Result := TSmartPointer<TList<TTest>>.Create();

 for I := 0 to 5 do
  begin
    lTTest := TSmartPointer<TTest>.Create();
    lTTest.FString := IntToStr(i);

    Result().Add(lTTest);
  end;
end;

var Testlist:ISmartPointer<TList<TTest>>;
    i: Integer;

begin
  try
   Testlist := TestSMP();

   for I := 0 to 5 do
    Writeln(Testlist[i].FString);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
 Writeln('finished');
 Readln;
end.

The problem is that I cannot access the items from the list, and I do not know where the problem is.

+2
source share
1 answer
function TestSMP(): ISmartPointer<TList<TTest>>;
var 
   lTTest: ISmartPointer<TTest>;
   i: Integer;
begin
   Result := TSmartPointer<TList<TTest>>.Create();

   for I := 0 to 5 do
   begin
      lTTest := TSmartPointer<TTest>.Create();
      lTTest.FString := IntToStr(i);

      Result().Add(lTTest);
   end;
end;

An interface variable lTTestis the only thing that supports instances TTest. Each time around the loop, when you assign lTTest, the previous instance is TTestdestroyed. When the function completes, the last instance is TTestdestroyed containing '5'. All the cases you lovingly created are now dead.

, TSmartPointer<T>.Destroy . , TTest . , , , .

, , . , .

ISmartPointer<TList<TTest>>

ISmartPointer<TList<ISmartPointer<TTest>>>

, TTest, -. , .

:

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Generics.Collections;

type
  ISmartPointer<T> = reference to function: T;

  TSmartPointer<T: class, constructor> = class(TInterfacedObject,
    ISmartPointer<T>)
  private
    FValue: T;
  public
    constructor Create;
    destructor Destroy; override;
    function Invoke: T;
  end;

  TTest = class
    FString: string;
  end;

constructor TSmartPointer<T>.Create;
begin
  inherited;
  FValue := T.Create;
end;

destructor TSmartPointer<T>.Destroy;
begin
  FValue.Free;
  inherited;
end;

function TSmartPointer<T>.Invoke: T;
begin
  Result := FValue;
end;

function TestSMP(): ISmartPointer<TList<ISmartPointer<TTest>>>;
var
  lTTest: ISmartPointer<TTest>;
  i: Integer;
begin
  Result := TSmartPointer<TList<ISmartPointer<TTest>>>.Create();

  for i := 0 to 5 do
  begin
    lTTest := TSmartPointer<TTest>.Create();
    lTTest.FString := IntToStr(i);
    Result().Add(lTTest);
  end;
end;

var
  i: Integer;
  Testlist: ISmartPointer<TList<ISmartPointer<TTest>>>;

begin
  Testlist := TestSMP();
  for i := 0 to 5 do
    Writeln(Testlist[i]().FString);
  Writeln('finished');
  Readln;
end.

0
1
2
3
4
5
finished

, ISmartPointer<TList<ISmartPointer<TTest>>>. , Delphi.

+4

All Articles