Should I put a try-finally block after every Object.Create?

后端 未结 8 1365
青春惊慌失措
青春惊慌失措 2021-02-04 17:11

I have a general question about best practice in OO Delphi. Currently, I put try-finally blocks anywhere I create an object to free that object after usage (to avoid memory leak

8条回答
  •  执笔经年
    2021-02-04 18:04

    In my opinion, there is only one reason an objects construction should not be followed by (or "in" as Mason pointed out) a try / finally block.

    1. If an objects' lifetime is being managed by another object.

    This management can take three forms:

    1. An object's reference has a scope beyond the local block and is freed elsewhere - like a field member freed in the destructor.
    2. An object immediately added to a list which is in charge of freeing the object later.
    3. An object with an associated lifetime manager, like how you pass the owner to a VCL control on construction.

    With #1, when the reference has a broader scope, the reference should be set to nil immediately if it isn't constructed right away. That way when it is checked for reference you know you have an accurate reading. This is most common with member objects that are constructed as part of a larger class, and then cleaned up when the parent object is destroyed.

    With #2, when an object is added to a list, you want to use a try-except block (one of the few times I use one) just in case an exception occurs after the object is constructed and before it is added to the managing list. Ideally the first line after the construction is adding it to the list, or the list is actually a factory class that gives you an object already added to the list.

    With #3, when an object has another lifetime manager, you really should make sure having it managed by that manager is the right thing to do. If you are constructing a VCL control, you may be tempted to have the form (or any other control) own it, but that actually puts additional overhead on the construction and destruction. If possible you should explicitly free it, this is especially true if you put the control on once, then you know you will be freeing it in your form's destructor or when it closes. The only time you can't do this is if the control creation is more dynamic.

    So yes, it is a best practice to use a lot of try / finally blocks. You should only have a few try / except blocks, and most all of them should trap very specific exception types, and / or re-raise the exception. If you have more try / except than try / finally blocks, then you are doing it wrong.

提交回复
热议问题