When you read about a particular implementation of OOP mechanisms, it is very funny to see how one or another specific feature of a particular language or library is called “obvious”. The description of OOP in C ++ is particularly notable in this respect, in which, in fact, the implementation is one of the most opaque and confusing.
So, I will not write anything about the obvious, but tell you about a way to make life easier at critical points in the life cycle of objects, using not “obvious”, but very useful features of the implementation of OOP in Delphi.
Handling inability to complete object creation in constructor
If the constructor stores its data only in the fields of the object, then the solution is elementary - it is enough to raise an exception. RTL Delphi will intercept it itself, call the destructor, release the occupied memory, and throw an exception again.
Accordingly, if part of the data for construction is stored in global variables, then it is enough to use the usual try..except block with re-raising the exception.
From here, two requirements for destructors are derived: not to provoke exceptions, which means not to try to do anything other than freeing up resources (for example, saving settings) and be sure to support ...
Deleting a partially initialized object
In Delphi, this presents no difficulties, since any object, even before transferring control to the constructor, is initialized with zeros. Accordingly, in the destructor it is enough to correctly handle null values, in which the FreeAndNil procedure, which frees an object, only helps if the reference to it is no longer nil.
')
Order call constructors
In Delphi, it doesn't matter. You can call ancestor constructors, other constructors of the same class in the same way as usual methods or do not call anything - so if you need to use ancestor initialization, then it is not recommended to forget to call it, but you should do something before or instead of calling a constructor there is no ancestor.
Calling virtual methods in the constructor
Since in Delphi the object is immediately initialized by the final reference to VMT, there is no difference between the other virtual method calls from the constructor from the other options.
Virtual constructors and class references
In Delphi, constructors can be virtual. The point of such a feature is the ability to create objects with an unknown class at the compilation stage without the need to implement a factory. For this purpose, variables are used with reference to a class (and not an object!), For which the virtual constructor can be called by obtaining an instance of the corresponding class or its descendant, depending on the value of the reference.
Automatic control of object lifetime
If an object implements this or that explicitly specified interface, then it can be cast to a reference to this interface using an assignment or an operation as. In this case, Delphi itself will generate calls to IUnknown methods, which allows you not to query interfaces and not explicitly delete objects.
Results
On the one hand, all of the above should be known to every developer; on the other hand, I have met not so many programmers with experience, inventing bicycles only from not knowing the features of implementing my working tool. Hope this article helps a bit. Of the useful features of OOP implementation in Delphi, support for delegating the implementation of interfaces has not been considered, but this is a topic for a separate article.