Я новичок в Delphi с опытом работы на C ++ и пытаюсь понять, как можно реализовать интеллектуальные указатели. Я наткнулся на следующий пост, который пытаюсь использовать в качестве отправной точки: Delphi - умные указатели и дженерики TList
Однако я не могу скомпилировать предыдущий код с помощью Delphi XE7 (ошибки компилятора отображаются в виде комментариев в коде). Также я был бы очень признателен, если бы кто-нибудь действительно объяснил логику кода (сначала я хотел использовать этот класс как вспомогательный класс, но теперь я хотел бы понять, что на самом деле происходит). Я смутно понимаю, что, поскольку реализация интеллектуального указателя наследуется от TInterfacedObject, ссылки учитываются, но все остальное для меня не имеет смысла :)
unit SmartPointer;
interface
uses
SysUtils, System.Generics.Collections;
type
ISmartPointer<T> = reference to function: T;
// complains ISmartPointer<T> expecting an interface type
TSmartPointer<T: class, constructor> = class(TInterfacedObject,ISmartPointer<T>)
private
FValue: T;
public
constructor Create; overload;
constructor Create(AValue: T); overload;
destructor Destroy; override;
function Invoke: T;
end;
implementation
{ TSmartPointer<T> }
constructor TSmartPointer<T>.Create;
begin
inherited;
FValue := T.Create;
end;
// complains: overload procedure TSmartPointer.Create must be marked with the overload directive
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
FValue.Free;
inherited;
end;
function TSmartPointer<T>.Invoke: T;
begin
Result := FValue;
end;
end.
Пытался использовать предыдущий интеллектуальный указатель со следующим тестовым кодом, что привело к ошибке компилятора… что мне не хватает?
program TestSmartPointer;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, SmartPointer;
type
TPerson = class
private
_name : string;
_age : integer;
public
property Name: string read _name write _name;
property Age: integer read _age write _age;
end;
var
pperson : TSmartPointer<TPerson>;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
pperson := TSmartPointer<TPerson>.Create();
// error on next line: undeclared Identifier: Name
pperson.Name := 'John Doe';
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Free
что-то, что находится под охраной умного указателя. Каждыйtry-finally-end
- это то, что нужно закодировать вручную, и это нарушает DRY, IMO. Поэтому мне интересно, почему люди на самом деле думают, что умные указатели Delphi - плохая идея. Компилятор гораздо лучше справляется с такими вещами, чем человек-программист. Это похоже на обсуждение переключения передач по сравнению с автоматическим. Я предпочитаю автомат, хотя мне нравится спортивное вождение. - person Rudy Velthuis   schedule 02.04.2015