Jump to content

Recommended Posts

I've been reading this article (and comments) https://community.idera.com/developer-tools/b/blog/posts/try-finally-blocks-for-protecting-multiple-resources-in-delphi

Even thought it talks about protecting multiple classes (resources), I'm referring to single class:

 

In most cases (or all) we wrap using Class after create with try... finally:

var vMyClass: TMyClass;
begin
  vMyClass := TMyClass.Create;
  try
    ... using vMyClass...
  finally
    vMyClass.Free;
  end;
end;

I assume that the only time creating class fails is when class constructor fails (it tries to execute some code that fails). Is that correct?

If this is correct (that constructor is the only point of failure) then if there is no constructor defined in specific class - we don't need try...finally?

 

Or are there other situations that creating class can fail?

 

 

 

Share this post


Link to post

The try finally here isn't protecting the execution of the constructor. It protects against exceptions in the code that runs after the constructor completes, after the try.

 

Look at the code in your post. The try finally is not active when the constructor runs. If an exception is raised in the constructor then the try is never reached.

 

So, yes, you do need the try finally. 

  • Thanks 1

Share this post


Link to post

OK, I understand, make sense.

One last thing I'm still struggling with: can Create not actually create class and 'return/ or leave' variable as nil, but it also doesn't raise exception? this is probably not possible, right?

Share this post


Link to post

Two things can happen

 

1. The constructor succeeds and returns a valid object reference. 

2. An exception is raised, propagates out of the constructor, and the assignment never happens. 

  • Thanks 1

Share this post


Link to post

 

7 minutes ago, David Heffernan said:

and the assignment never happens. 

aha... exception stops the flow and next/upper try...finally/except handles it - outside the current method. OK.

 

I do always use try.. finally, but I thought we are safeguarding the usage of class in case variable is nil, if create fails. Never questioned it, until today 🙂

Now I understand. Thanks!

 

Share this post


Link to post

Just one remark here: If the constructor raises an exception, the destructor will be called automatically. You must always be aware that the destructor might run on an only partially initialized instance.

Edited by dummzeuch
  • Like 2

Share this post


Link to post
1 hour ago, dummzeuch said:

Just one remark here: If the constructor raises an exception, the destructor will be called automatically. You must always be aware that the destructor might run on an only partially initialized instance.

...and should never raise exception itself

  • Like 1

Share this post


Link to post
Guest
15 minutes ago, Fr0sT.Brutal said:

...and should never raise exception itself

That is impossible in case out of memory !, right ?

so it might happen and even if your constructor is using utilizing try..except the application is doomed and the best way to raise an exception and collapse in controlled way, not just close, or stop the process and clean up ad out live the out of memory situation, most application can't.

Share this post


Link to post
39 minutes ago, Kas Ob. said:

That is impossible in case out of memory !, right ?

so it might happen and even if your constructor is using utilizing try..except the application is doomed and the best way to raise an exception and collapse in controlled way, not just close, or stop the process and clean up ad out live the out of memory situation, most application can't.

He was talking about the destructor, not the constructor. It's very unlikely that a destructor runs into an out of memory condition. Yes it can happen, but usually it's the constructor that fails due to it, not the destructor.

Share this post


Link to post
Guest

I should have asked first what he meant with that phrase !

Share this post


Link to post

There are situations where the ctor can fail, for sure. So you put it in a try...except.

 

The try...finally is partly to ensure that properly constructed instances get freed in case an exception is thrown.

 

But more than that, if you call Exit at any point between the 'try' and 'finally', the Exit goes to the Finally clause as well.

 

It helps to think of things in your mind as always composed as three parts:

 

* set-up or initialization

* operation

* tear-down

 

For example:

 

* You set up some scaffolding on a wall to do some work on second-story windows.

* You do whatever it was you intended to do

* You tear down the scaffolding, pack up and go home.

 

If you fall off the scaffolding (like throwing an exception) an ambulance comes and takes you away. But someone has to tear things down and clean up, right?

 

Now say you get a call from someone saying you won the lottery. You probably want to rush off and claim your money (like calling Exit). You still want to be sure that everything gets torn down and cleaned up as well.

 

This is a frequently repeating pattern in any program. When you start to see it, you can't un-see it, and it makes organizing things far easier. Ditto for finding stuff. It's how classes are structured, how you can organize units, how you organize chunks of code inside of a unit, and even within methods. Classes make it explicit with the notion of a "constuctor" and "destructor". Try...Finally and Try...Except blocks do the same thing, but the "constructor" part is above the Try. The difference is that the 'except' is provided specifically to trap exceptions while 'finally' is to act more like a destructor to clean things up.

Edited by David Schwartz
  • Thanks 1
  • Haha 1

Share this post


Link to post
8 hours ago, David Schwartz said:

So you put it in a try...except

Well not necessarily. Typically you let exceptions float upwards to be handled by some high level exception handler. 

 

  • Like 3

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×