[fpc-pascal]Classes/Objects/Pointers / Pointer Help

Thomas Schatzl tom_at_work at yline.com
Mon Feb 10 15:00:35 CET 2003


From: "James Mills" <prologic at prologitech.com>
Sent: Monday, February 10, 2003 2:04 PM
Subject: Re: [fpc-pascal]Classes/Objects/Pointers / Pointer Help

Hi,

> Yes ok, fair enough, this much is in my knowledge of Pascal :) hehe, but
> the real question is, how do you create these objects on the fly in a
> program, ie: dynamic array...
> I have tried using plain objects, and have failed in frustration. When
> you suggested using classes, it worked right away (of course :P).

If you're bound to 1.0.6 which doesn't support dynamic arrays by using
compiler magic you have to do it like this:

-----------
program Project1;

uses
  SysUtils; { IntToStr() }

type
  PMyObject = ^TMyObject;

  { note: this is our template for our object container array. With the
  upper bound set to zero you might get range check errors while
  compiling and run time errors if you turn runtime range checking on...
  You could set the upper bound to a ridiculously high value if this
  disturbs you (since it's just a template and not really allocated
  anywhere). I assume that the number of elements is dynamic though, so
  if you *know* that you only need 5 elements max it's better to say
  that here.
  Better might be using dynamic arrays available in FPC 1.1 than this
  construct. And even better might be (depending on your needs)
  other concepts to store data dynamically, e.g. linked lists (see
  the 'net or any introductionary algorithm book).
  }
  TMyObjectArr = array[0..0] of PMyObject;

  { big note: better use the Object pascal 'classes' concept instead of
  'objects'... see FPC reference guide chapter 4 and 5 respectively - but
  I'll stick to old-fashioned objects here :-) }
  TMyObject = object
  private
    fString : String;
  public
    constructor Init(s : String);
    { note: the empty brackets after methods are sort of personal coding
convention }
    destructor Done();
    procedure DoSomething();
  end;

constructor TMyObject.Init(s : String);
begin
  Writeln('Calling Init...');
  fString := s;
end;

destructor TMyObject.Done();
begin
  Writeln('Calling Done...');
end;

procedure TMyObject.DoSomething();
begin
  Writeln(fString);
end;

var
  dynObjArr : ^TMyObjectArr;
  i : Integer;

begin
  { initialize container (assume we need 5 elements) }
  getmem(dynObjArr, sizeof(PMyObject) * 5);
  { since we overwrite all elements later on this isn't really required }
  for i := 0 to 5-1 do begin
    dynObjArr^[i] := nil;
  end;

  for i := 0 to 5-1 do begin
   dynObjArr^[i] := new(PMyObject, Init('Hello World (' + IntToStr(i) +
')'));
  end;

  { [....]
   display a few of the elements in the array... }
  Writeln('Looking what''s inside...');
  for i := 2 to 5-1 do begin
   dynObjArr^[i]^.DoSomething();
  end;

  { [....]
   free the 2nd element (index 1) }
  Writeln('Freeing one element...');
  dispose(dynObjArr^[1], Done());
  { convention: invalid element entries are nil'ed; if you iterate
   over the element to do something with them *don't* call nil'ed
   elements... (didn't check this here in all the output loops at all
   though) }
  dynObjArr^[1] := nil;

  { stick another one in its place }
  Writeln('Putting another element into the array...');
  dynObjArr^[1] := new(PMyObject, Init('Good Bye'));

  { display them all again }
  Writeln('Looking what''s inside...');
  for i := 0 to 5-1 do begin
   dynObjArr^[i]^.DoSomething();
  end;

  Writeln('Removing everything...');
  for i := 0 to 5-1 do begin
   dispose(dynObjArr^[i], Done());
  end;

  { remove container }
  freemem(dynObjArr, sizeof(PMyObject) * 5);
  readln;
end.
---------

I hope this addresses your questions.

Regards,
  Thomas




More information about the fpc-pascal mailing list