[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