About the "obvious" and useful or the creation and destruction of Delphi objects

    When you read about a particular implementation of OOP mechanisms, it is very funny to see how a particular feature of a particular language or library is called "obvious." The description of OOP in C ++ is especially notable in this respect, in which the implementation is one of the most opaque and confusing.
    So, I will not write anything about the evidence, but I will talk about a way to make life easier for you at critical points in the life cycle of objects using not “obvious”, but very useful features of the implementation of OOP in Delphi.


    Handling the inability to complete object creation in the 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 itself will intercept it, call the destructor, free up used 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 the repeated raising of an exception.
    This leads to two requirements for destructors: not to provoke exceptions, which means not trying 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 does not present any difficulties, since any object is initialized to zeros even before the control is transferred to the constructor. Accordingly, in the destructor it is enough to correctly process null values, which is greatly helped by the FreeAndNil procedure, which frees the object only if the reference to it is no longer nil.

    Constructor call order


    In Delphi, it does not matter. You can call the constructor of the ancestor, other constructors of the same class in the same way as ordinary methods or not call anything - so if you need to use the initialization of the ancestor, it is not recommended to forget to call it, but there is something to do before or instead of calling the constructor there are no ancestors.

    Calling virtual methods in the constructor


    Since in Delphi the object is immediately initialized with a final reference to VMT, there is no difference between calls to virtual methods from the constructor from other options.

    Virtual constructors and class references


    In Delphi, constructors can be virtual. The meaning of this 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 with a reference to the class (and not an object!) Are used, for which you can call the virtual constructor by obtaining an instance of the corresponding class or its descendant, depending on the value of the link.

    Automatic control of the lifetime of an object


    If an object implements one or another explicitly specified interface, then it can be brought to a link to this interface using assignment or operation as. In this case, Delphi will itself generate IUnknown method calls, which allows us not to request interfaces and not to delete objects explicitly.

    Summary


    On the one hand, every developer should know all of the above; on the other hand, I met not so few experienced programmers who invented bicycles only because they did not know the specifics of implementing their working tool. Hope this article helps a bit. Of the useful features of the OOP implementation in Delphi, support for delegating the implementation of interfaces remained unexamined, but this is a topic for a separate article.

    Also popular now: