Как использовать умный указатель на конструкторе по умолчанию - PullRequest
0 голосов
/ 23 июня 2019

Итак, я снова изучаю новые вещи и наткнулся на Smart Pointers.У меня был код

procedure TForm3.BitBtn1Click(Sender: TObject);
var
  _StringList: ISmartPointer<TStringList>;
begin
  _StringList := TSmartPointer<TStringList>.Create(TStringList.Create);
end;

Как видите, объявление переменных довольно странно, и необходимо упрощение.Я сталкивался с другим решением

procedure TForm3.btnDelphiClick(Sender: TObject);
var
  _StringList: TStringList;
begin
  _StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create(False));
end;

К сожалению, оно не работает с конструктором без параметров

procedure TForm3.btnDelphiClick(Sender: TObject);
var
  _StringList: TStringList;
begin
  _StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create);
end;

[dcc32 Ошибка] Main.pas (47): E2089 Недопустимый тип

Мне здесь не повезло?PS Я знаю, что некоторые из вас будут утверждать, что я должен придерживаться попытки ... окончательно заблокировать, но это из любопытства.

unit SmartGuard;

interface

type
  IGuard = interface
  ['{CE522D5D-41DE-4C6F-BC84-912C2AEF66B3}']
  end;

  TGuard = class(TInterfacedObject, IGuard)
  private
    FObject: TObject;
  public
    constructor Create(AObject: TObject);
    destructor Destroy; override;
  end;

  SmartGuard<T: class> = record
  private
    FGuard: IGuard;
    FGuardedObject: T;
  public
    class operator Implicit(GuardedObject: T): SmartGuard<T>;
    class operator Implicit(Guard: SmartGuard<T>): T;
  end;

implementation

uses
  {Delphi}
  System.SysUtils
  {Project}
  ;

constructor TGuard.Create(AObject: TObject);
begin
  FObject := AObject;
end;

destructor TGuard.Destroy;
begin
  FObject.Free;
  inherited;
end;

{ SmartGuard }

class operator SmartGuard<T>.Implicit(GuardedObject: T): SmartGuard<T>;
begin
  Result.FGuard := TGuard.Create(GuardedObject);
  Result.FGuardedObject := GuardedObject;
end;

class operator SmartGuard<T>.Implicit(Guard: SmartGuard<T>): T;
begin
  Result := Guard.FGuardedObject;
end;

end.

Я хотел бы найти решение, которое не требовало бы дополнительного вызова методакак здесь https://github.com/marcocantu/DelphiSessions/blob/master/DelphiLanguageCodeRage2018/02_SmartPointers/SmartPointerClass.pas например _StringList.Value.Add('foo'); и «специальные» скобки, например _StringList := TSmartPointer<TStringList>.Create(TStringList.Create)();

1 Ответ

1 голос
/ 23 июня 2019

Компилятору нужна помощь в устранении неоднозначности

TStringList.Create

Компилятор не знает, является ли это ссылкой на метод или вызовом метода.

Устраните неоднозначность, добавив символы скобки, чтобы указать, что это вызов.

_StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create());
...