Delphi 12 is in the works. One of its small features that will have a huge impact is a change in the default handling of floating-point exceptions, which will now be masked on all platforms. Previously, floating-point exception handling was different across platforms, and most notably on the Windows platform: In VCL and console applications, floating-point exceptions were not masked and would raise an exception. On the other hand, FireMonkey applications had all floating-exceptions masked by default, regardless of which platform they were running on. Basically if you haven't explicitly changed the exception mask in your code to some value other than the default, and you had code that attempted to divide some number with zero, you would get an EZeroDivide exception in previous Delphi versions on the Windows VCL application. In Delphi 12, there is no exception, and the result of such a division will be +INF . So the following code will no longer raise an exception. If you were r...
Here's some questions in advance for you (which I'll have to catch on the replay (hint, hint) due to timezones).
ReplyDeleteWhat's your thoughts on The Wiert Corner's aversion to using AfterConstruction? (see his blog post 2021/03/23)
For method parameters what data types do you make const rather than leaving them as a ordinary value parameter? These days I'm using const routinely for strings, interfaces and anonymous methods. I had started doing it for TObject descendants when there was the possibility of my code being run under ARC but I've since removed the consts from those.
I forgot about records. I routinely const those as well.
DeleteAfterConstruction is safe and IMO not used enough. Modifying base class and adding additional virtual DoCreate method is fine, too, if you have base class and you have reasons for not making constructor virtual. But, I would still prefer using it more for configuration than for constructing instances - in other words for final setup after you know all pieces of the object are fully constructed, but that also depends on particular use case. If you need speed, then using AfterConstruction rather than adding new virtual methods is faster.
DeleteThe only part where you need to be careful with AfterConstruction is with reference counted classes and triggering reference counting inside AfterConstruction after you called inherited method - that will cause self destruction of the object. See: https://dalijap.blogspot.com/2019/12/self-destructing-object-instance.html
Also, regardless of the exceptions raised in AfterConstruction, full cleanup will run including BeforeDestruction and Destroy. So that part was not fully correct at least not for newer versions. In Delphi 7 BeforeDestruction is not called, but destructor is. In XE4+ both BeforeDestruction and Destroy are called.
Anyway, since destructor must be able to handle cleanup of partially constructed objects anyway, BeforeDestruction is necessary only seldom, as anything created there can be cleaned up in Destroy.
For parameters, I am following same logic you do. I also use it for larger records if I don't need to modify it - it allows compiler to optimize and avoid copying the whole record.
I couldn't help myself answering your questions here... but I will mention that topic on the webinar, too :)
Delete