[fpc-pascal]Polymorphism of class field
Full_Name
memsom at post.interalpha.co.uk
Thu Aug 30 11:10:31 CEST 2001
Quoting Michael Van Canneyt <michael.vancanneyt at wisa.be>:
> You can't.
Although it might get messy, surely he could defire a variant record? Something
like:
type
TStackElemType = (stNull, stString, stReal);
TStackElem = record
ElemType: TStackElemType;
case tag: integer of
0: (RealResult: Real);
1: (StringResult: String[255]);
end;
PStackelem = ^TStackElem;
procedure setStringElemData(st: string); //sets Elemtype to 'stReal'
procedure setRealElemData(re: real); //sets Elemtype to 'stString'
procedure CrearElem; //sets Elemtype to 'stNull'
But, to be honest, if you go that far you may as well use classes.
A more elegant solution is to go the Smalltalk route, and create classes that
descend from a single ancestor. But that's not actually all that easy or
gracefull in Pascal.
I think a more worrying thing is your following class:
> > type
> >
> > TStackElem = class
> > public
> > constructor Init; virtual;
> > destructor Done; virtual;
> > Prolog : TRPLObjectType;
> > Next : TStackElem;
> > function Decomp : string; virtual; abstract;
> > end;
This class will never call 'Done'. Not in the Delphi sense of the word. Try the
following:
destructor TStackElem.Done;
begin
//whatever you already did
writeln('hello, I have destroyed myself');
//whatever you already did
end;
You will never see the line 'hello, I have destroyed myself' unless you
explicitly call 'done' and that is wrong. What you should actually do (and this
is in the standard btw, it's not just me being pedantic) is call 'free'.
Because Delphi has a policy of only having a single destructor, and this
through polymorphism should be called 'destroy' and should be 'overridden' you
are *never* freeing your resources. You may as well change the Destructors name
to 'HelloIamAMemoryLeak'.
Before anyone jumps on me, this is tested under FPC 1.02 *and* FPC 1.04,
compiled with '-S2'. The destructor never gets called if you call 'free'. It
would be *really* nice if you could write this into the docs for 1.2, I expect
it's already there, but it's obviously not evident coz people keep making this
mistake. If you're going to allow people to use Delphi stle classes, they
should always inherit from TObject (even if the user doesn't specify this) and
therefore the destructor has to be called Destroy.
Breaking this is really bad, unless calling 'done' directly does
call 'destroy'. I note however that if I create a class with 2 destructors,
firstly FPC1.04 complains that I do have 2, and secondly only 'done' gets
called if I call 'done' and only 'destroy' gets called if I call 'free'.
Sorry to moan again, but this is something that will cause many people problems
if it's not addressed. The simplest, cheapest and less painfull would be
to 'warn' people if they are using 'class' style constructs and
their 'destructor' is not called 'destroy'.
Matt
--
"Computer games don't affect kids; I mean if Pac-Man affected us as kids,
we'd all be running around in darkened rooms, munching magic pills and
listening to repetitive electronic music."
Kristian Wilson,
Nintendo, Inc, 1989
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w
O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+
G e++ h--- r+++ y+++
------END GEEK CODE BLOCK------
More information about the fpc-pascal
mailing list