Title: How to implement a Smart Pointer Class C almost
unit Unit2;
interface
uses
 Classes;
type
 TSmartPointer = class(TComponent)
 private
 FPointer: Pointer;
 FReadOnly: Boolean;
 FOwnsMemory: Boolean;
 function GetIsNil: Boolean;
 procedure SetPointer(const Value: Pointer);
 public
 constructor Create(AOwner: TComponent); overload; override;
 constructor Create(AOwner: TComponent; APointer: Pointer; AOwnsMemory: Boolean = True);
 overload;
 destructor Destroy; override;
 property Memory: Pointer read FPointer write SetPointer;
 property OwnsMemory: Boolean read FOwnsMemory write FOwnsMemory;
 property IsReadOnly: Boolean read FReadOnly write FReadOnly;
 property IsNil: Boolean read GetIsNil;
 procedure FreeMemory;
 function AssignMemory(APointer: Pointer): Boolean;
 end;
implementation
{ TSmartPointer }
function TSmartPointer.AssignMemory(APointer: Pointer): Boolean;
begin
 Result := False;
 if not FReadOnly then 
 begin
 FPointer := APointer;
 Result := (FPointer = APointer);
 end;
end;
constructor TSmartPointer.Create(AOwner: TComponent);
begin
 inherited;
 FOwnsMemory := True;
 FPointer := nil;
 FReadOnly := False;
end;
constructor TSmartPointer.Create(AOwner: TComponent; APointer: Pointer;
 AOwnsMemory: Boolean);
begin
 inherited Create(AOwner);
 FOwnsMemory := AOwnsMemory;
 FPointer := APointer;
 FReadOnly := False;
end;
destructor TSmartPointer.Destroy;
begin
 if FOwnsMemory = True then Dispose(FPointer);
 FPointer := nil;
 inherited;
end;
procedure TSmartPointer.FreeMemory;
begin
 Dispose(FPointer);
 FPointer := nil;
end;
function TSmartPointer.GetIsNil: Boolean;
begin
 Result := (FPointer = nil);
end;
procedure TSmartPointer.SetPointer(const Value: Pointer);
begin
 if not FReadOnly then FPointer := Value;
end;
end.
(*-------------------------------------------------------------------
Here is a sample form to see its usage:
--------------------------------------------------------------------*)
unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Unit2, StdCtrls;
type
 TForm1 = class(TForm)
 Button1: TButton;
 procedure FormCreate(Sender: TObject);
 procedure Button1Click(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
var
 Form1: TForm1;
 ATextPointer: TSmartPointer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
 A: ^String;
begin
 New(A);
 ATextPointer := TSmartPointer.Create(Form1, A, True);
 string(ATextPointer.Memory^) := 'a pascal smart pointer stored this text!';
 Self.Caption := string(ATextPointer.Memory^);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
 APointer: TSmartPointer;
 ACanvas: TCanvas;
begin
 ACanvas := TCanvas.Create;
 APointer := TSmartPointer.Create(Form1, @ACanvas, False);
 with TCanvas(APointer.Memory^) do 
 begin
 Handle := GetWindowDC(Form1.Handle);
 Brush.Color := clMoneyGreen;
 FillRect(Rect(0, 0, Form1.Width, 23));
 Font.Size := 10;
 Font.Color := clGreen;
 Font.Style := [fsBold];
 TextOut((Form1.Width div 2) - (TextWidth(string(ATextPointer.Memory^)) div 2),
 3, string(ATextPointer.Memory^));
 end;
end;
end.