[fpc-devel] Modifiers...
Sven Barth
pascaldragon at googlemail.com
Thu Feb 1 21:14:13 CET 2024
Am 29.01.2024 um 21:56 schrieb Michael Van Canneyt via fpc-devel:
> I didn't say I cannot think of a legitimate use. I said it does not make
> sense to me, as in
>
> "I don't understand what people try to accomplish with this modifier".
>
> Unfortunately I still don't understand after your explanation what
> adding 'final' is supposed to accomplish. It may well be legitimate,
> but I have currently no opinion as I don't understand it.
>
> Maybe an actual code example would be more enlightening.
>
> That way I can also add it to the docs once I understand the intended
> use myself.
It took me a while to find a suitable example, but now I've got one
that's sounds useful.
Assume you have a class TCleanup that deals with cleaning up some stuff
with a virtual (maybe abstract) method named DoCleanup:
=== code begin ===
type
TCleanup = class
public
procedure DoCleanup; virtual;
end;
=== code end ===
Now assume there's a child class that does some very specific stuff in
its DoCleanup method that relies on the order and where a user may only
customize it a specific part:
=== code begin ===
type
TWhateverCleanup = class
private
procedure Step1;
procedure Step2;
procedure Step3;
protected
procedure DoCustomCleanup; virtual;
public
procedure DoCleanup; override;
end;
procedure TWhateverCleanup.DoCleanup;
begin
Step1;
Step2;
DoCustomCleanup;
Step3;
end;
=== code end ===
Now as the class is now someone that inherits from TWhateverCleanup
might override DoCleanup, but adding something in front of or after the
DoCleanup call would be wrong.
The ability to declare the method DoCleanup as final makes it clear to
someone who inherits from the class, that no, you should not modify
that, use a different way (in this case DoCustomCleanup) to customize
its behavior.
And when I came upon this example I noticed that we use a similar scheme
inside the compiler:
The tdef and tsym descendants have a virtual ppuwrite method. These
classes have platform specific implementations so that e.g. the m68k
tparavarsym descendant can write the register location for the syscall
calling convention to the PPU. However due to how the writing to a PPU
is implemented it's a bad idea to override the platform independant
ppuwrite method, call inherited and then write the custom stuff. This
had already led to problems in the past. Thus Jonas had introduced a new
virtual ppuwrite_platform method that is supposed to be implemented by
the platform specific descendants and made the platform independant
ppuwrite implementations in the specific tdef and tsym implementations
final so that no one that inherits from the tdef/tsym descendants gets
the idea to mess inside that method again.
I've learned - during my research - that this is called "safe design".
Regards,
Sven
More information about the fpc-devel
mailing list