Mike Torrettinni 198 Posted August 11, 2020 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
David Heffernan 2345 Posted August 11, 2020 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. 1 Share this post Link to post
Mike Torrettinni 198 Posted August 11, 2020 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
David Heffernan 2345 Posted August 11, 2020 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. 1 Share this post Link to post
Mike Torrettinni 198 Posted August 11, 2020 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
dummzeuch 1505 Posted August 12, 2020 (edited) 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 August 12, 2020 by dummzeuch 2 Share this post Link to post
Fr0sT.Brutal 900 Posted August 12, 2020 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 1 Share this post Link to post
Guest Posted August 12, 2020 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
dummzeuch 1505 Posted August 12, 2020 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 Posted August 12, 2020 I should have asked first what he meant with that phrase ! Share this post Link to post
David Schwartz 426 Posted August 18, 2020 (edited) 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 August 18, 2020 by David Schwartz 1 1 Share this post Link to post
David Heffernan 2345 Posted August 19, 2020 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. 3 Share this post Link to post