如何在默认构造函数上使用智能指针
How to use smart pointer on default constructor
因此,我再次学习新事物并且遇到了智能指针。我有代码
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 类型转换无效
我在这里运气不好吗?
P.S。我知道你们中的一些人会争辩说我应该坚持尝试..最终阻止,但这是出于好奇。
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.
我很想找到一个不需要额外 "method" 调用的解决方案 https://github.com/marcocantu/DelphiSessions/blob/master/DelphiLanguageCodeRage2018/02_SmartPointers/SmartPointerClass.pas 例如_StringList.Value.Add('foo');
和 "special" 括号,例如_StringList := TSmartPointer<TStringList>.Create(TStringList.Create)();
编译器需要帮助消除歧义
TStringList.Create
编译器不知道这是对方法的引用,还是对方法的调用。
通过添加括号来消除歧义以表明它是一个调用。
_StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create());
因此,我再次学习新事物并且遇到了智能指针。我有代码
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 类型转换无效
我在这里运气不好吗? P.S。我知道你们中的一些人会争辩说我应该坚持尝试..最终阻止,但这是出于好奇。
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.
我很想找到一个不需要额外 "method" 调用的解决方案 https://github.com/marcocantu/DelphiSessions/blob/master/DelphiLanguageCodeRage2018/02_SmartPointers/SmartPointerClass.pas 例如_StringList.Value.Add('foo');
和 "special" 括号,例如_StringList := TSmartPointer<TStringList>.Create(TStringList.Create)();
编译器需要帮助消除歧义
TStringList.Create
编译器不知道这是对方法的引用,还是对方法的调用。
通过添加括号来消除歧义以表明它是一个调用。
_StringList := SmartGuard.SmartGuard<TStringList>(TStringList.Create());