Entropy Overload: Smart pointers in Delphi (original) (raw)
Strongly-typed smart pointers are now possible in Delphi, leveraging the work on generics. Here's a simple smart pointer type:
TSmartPointer<T: class> = record strict private FValue: T; FLifetime: IInterface; public constructor Create(const AValue: T); overload; class operator Implicit(const AValue: T): TSmartPointer; property Value: T read FValue; end;
Here it is in action, where TLifetimeWatcher is a little class that executes some code when it dies:
procedure UseIt; var x: TSmartPointer; begin x := TLifetimeWatcher.Create(procedure begin Writeln('I died.'); end); end;
Here's the full project code that defines TSmartPointer<>, TLifetimeWatcher, and the above test routine:
{$APPTYPE CONSOLE}
uses SysUtils;
type TLifetimeWatcher = class(TInterfacedObject) private FWhenDone: TProc; public constructor Create(const AWhenDone: TProc); destructor Destroy; override; end;
{ TLifetimeWatcher }
constructor TLifetimeWatcher.Create(const AWhenDone: TProc); begin FWhenDone := AWhenDone; end;
destructor TLifetimeWatcher.Destroy; begin if Assigned(FWhenDone) then FWhenDone; inherited; end;
type TSmartPointer<T: class> = record strict private FValue: T; FLifetime: IInterface; public constructor Create(const AValue: T); overload; class operator Implicit(const AValue: T): TSmartPointer; property Value: T read FValue; end;
{ TSmartPointer }
constructor TSmartPointer.Create(const AValue: T); begin FValue := AValue; FLifetime := TLifetimeWatcher.Create(procedure begin AValue.Free; end); end;
class operator TSmartPointer.Implicit(const AValue: T): TSmartPointer; begin Result := TSmartPointer.Create(AValue); end;
procedure UseIt; var x: TSmartPointer; begin x := TLifetimeWatcher.Create(procedure begin Writeln('I died.'); end); end;
begin try UseIt; Readln; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end.
Update: Fixed capture - was capturing a location in the structure, which of course will be freely copied etc.