Hello
Hello,
I've write some code to make purists cry :)
ARC on Records !
if Google can't translate the french page, just look a the code at the bottom of the page ;)
http://lookinside.free.fr/delphi.php?Destructor+sur+un+Record
I've write some code to make purists cry :)
ARC on Records !
if Google can't translate the french page, just look a the code at the bottom of the page ;)
http://lookinside.free.fr/delphi.php?Destructor+sur+un+Record
Is French `Mon` the same as English `My`?
ReplyDeleteI prefer abusing Anonymous methods: courtesy of Barry Kelly - http://blog.barrkel.com/2008/11/reference-counted-pointers-revisited.html
ReplyDelete--8<--
unit ObjHandle2;
interface
uses SysUtils;
type
TObjectHandle = class(TInterfacedObject, TFunc)
private
FValue: T;
public
constructor Create(AValue: T);
destructor Destroy; override;
function Invoke: T;
end;
implementation
constructor TObjectHandle.Create(AValue: T);
begin
FValue := AValue;
end;
destructor TObjectHandle.Destroy;
begin
FValue.Free;
end;
function TObjectHandle.Invoke: T;
begin
Result := FValue;
end;
end.
->8---
blog.barrkel.com - Entropy Overload: Smart pointers in Delphi
Jeroen Wiert Pluimers yes, "mon objet" is "my object", and "ma classe" is "my class", we don't have neutral gender in french..
ReplyDeleteDalija Prasnikar the purpose of my solution is to avoid any dynamic allocation, the record is fully static on the heap :)
ReplyDeleteYou can't out the record on the heap without dynamic allocation. That makes no sense. Did you mean that it's on the stack. It will be for a local variable. What about when it's the member field of a class?
ReplyDeletePaul TOTH You are already allocating wrapped object. If you are at point where it matters whether wrapper is heap or stack allocated, you should not be using SmartPointers anyway.
ReplyDeleteAlso, since it is a record you cannot pass your wrapper around unless you consort passing it as pointer...
David Heffernan my mistake, I mean "stack" and not heap of course..."pile" in french vs "tas".
ReplyDeleteIf it's member of a class, it will works also because Delphi calls finalize on the record, and finalize call the _Release method of the Interface.
Dalija Prasnikar I don't understand your last sentence...anyway this hack is a way to automatic call a destructor for a static record, my sample code use an Object but it can be anything else, like closing a file, releasing a pointer. Using an object with a overrided destructor was just an easy proof of concept.
ReplyDeletePaul TOTH What I meant when I said that you cannot pass record instance around is, since it is value type, you have to be careful not to make copies of it.
ReplyDeleteIt's clever, it can sometimes be useful
ReplyDeleteI've added two samples, one for Delphi 6, and the other with the "object" keyword, note that it works under Tokyo, but under Delphi 6, the herited interface is NOT released !
ReplyDeleteApart from the Barry Kelly implementation, you should also look at the Smart Pointer implementation and surrounding data types IManaged, TManaged, Managed and Managed in bitbucket.org - sglienke / Spring4D
ReplyDelete/ source / Source / Base / Spring.pas
— Bitbucket
Doesn't work in Delphi 6 (likely fails in anything below Delphi XE) but for me those are a thing from the past.
Jeroen Wiert Pluimers well Managed instanciate a TManaged, it's to avoid this allocation that my record use a "hacked" Interface )
ReplyDeleteAnyway, it was just a toy for me, I'm not sure I'll use it in production.
I've explored this because of my implementation of GDI+ flat API
TGraphics = record
private
Handle : Pointer;
public
function Create(ADC: HDC): TStatus; inline;
...
// GDI+ Graphics functions wrappers goes here
...
procedure Free; inline;
end;
function GdipCreateFromHDC(ADC: HDC; out AGraphics: TGraphics): TStatus; stdcall; external GDIP;
function GdipDeleteGraphics(var AGraphics: TGraphics): TStatus; stdcall; external GDIP;
function TGraphics.Create(ADC: HDC): TStatus;
begin
Result := GdipCreateFromHDC(ADC, Self);
end;
procedure TGraphics.Free;
begin
GdipDeleteGraphics(Self);
end;
var
G: TGrapchis;
begin
G.Create(Canvas.Handle);
....
G.Free;
end
Très bien mais quel intérêt?
ReplyDeleteDidier Tactisoft if you don't know what a destructor is for...I can't help you...même en français :)
ReplyDelete