0

Assume you have a TAncestorClass and its descendants TDescendantClass1 and TDescendantClass2. Also assume that the descendants differ from each other just in some differently overridden virtual methods. Otherwise all the fields are identical. That is, PHYSYCALLY the actual objects are the same, just their VMT differs.

TAncestorClass = class
  ...
  procedure VirtualProc; virtual; abstract;
  ...
end;

TDescendantClass1 = class(TAncestorClass)
  procedure VirtualProc; override;
end;

TDescendantClass2 = class(TAncestorClass)
  procedure VirtualProc; override;
end;

  

Nothing special so far.

The problem is that I want to dynamically change an already created object from TDescendantClass1 to TDescendantClass2 and vice versa, any time I need this thing. Not as ugly as it seems at first sight – as the objects are essentially the same. I just want the appropriate virtual methods to get called after each type change. Theoretically replacing the VMT (or just the zone from the VMT which differs) would be enough but this – otherwise simple and trivial hack – is extremely dirty, nobody wants to use such things in his code. But the ‘clean’ way – creating a new object with the right class, then copying and freeing the original one – is obviously out of question.

So, does somebody have a much more decent idea to do this?

Zoltán Bíró
  • 346
  • 1
  • 12
  • 3
    "*I want to dynamically change an already created object from `TDescendantClass1` to `TDescendantClass2` and vice versa*" - why? What possible use case could you have for doing this, even if it were possible? – Remy Lebeau Jun 29 '20 at 22:20
  • Why is 'the clean way' _obviously_ out of the question? – Toby Allen Jun 29 '20 at 22:22
  • @TobyAllen: speed. Just compare overwriting some entries in VMT to creating an object, then copying and freeing the other. – Zoltán Bíró Jun 29 '20 at 22:25
  • @RemyLebeau: The user modifies some parameters which leads to the need of reprocessing the page. The rendering process is essentially the same, just some minor things should behave a bit different. Want to keep the rendering procedure, the already created objects and to avoid many `if` statements in turn. – Zoltán Bíró Jun 29 '20 at 22:33
  • 5
    Might be easier to drop the multiple descendants and use method pointers which you reassign when you want the behavior to change. Works for the VCL and data access components - for example reassigning the OnClick of a button. – Brian Jun 29 '20 at 22:39
  • @Brian, not the most elegant possible, but definitely a good workaround. – Zoltán Bíró Jun 30 '20 at 04:56
  • 6
    There are lots of good ways to write code like this, but dynamic modification of vmt isn't one of them – David Heffernan Jun 30 '20 at 05:41
  • @DavidHeffernan, well, I’ll definitely follow @Brian’s suggestion as the simplest way to do what I need. Though I would still consider more elegant a built-in Delphi class procedure like this: `TDescendantClass2.Typecast(instance)`. – Zoltán Bíró Jun 30 '20 at 12:59
  • 1
    @ZoltánBíró I would consider that to be a complete abomination – David Heffernan Jun 30 '20 at 13:47
  • I agree with @Brian and DavidH. ISTM that fiddling with the VMT is trying to solve the wrong problem. – MartynA Jun 30 '20 at 14:20

0 Answers0