Re: is such exception handling approach good?



see below

On Fri, 21 Dec 2007 23:34:25 -0800 (PST), Abhishek Padmanabh
<abhishek.padmanabh@xxxxxxxxx> wrote:

On Dec 22, 11:33 am, ajk <a...@xxxxxxxxxxxx> wrote:
On Fri, 21 Dec 2007 17:36:15 +0200, "Alex Blekhman"

<tkfx.REM...@xxxxxxxxx> wrote:

It may be a good design, it may not be a good design from user's point
of view. The user might want to have a class wherein, by default he
doesn't get the connection created automatically on object creation.
But if it makes sense for the user of the class that those many
processings must be done automatically upon object creation, then from
C++ point of view it is achievable, with clarity and with stability.

####
the thing is that you are reasoning from the point of view that the
designer of the class is the same person that uses it. What-if for
instance you use a class somebody else wrote which throws an exception
but you do not know this. And you for some obscure reason - albeit not
a good design - declare such a class instance as global. great, how do
now handle the exception part from program showing a popup about
general exception error.

You can use some sort of a smart pointer that does automatic cleanup
on stack unwinding if exception is raised. You can call the release
resource API to free-up the resource on exception. You can close the
connection if something else in the constructor threw after opening
it. These all can be based on RAII and you would not need to do
anything specific for exception handling yourself. Here:

MyClass::MyClass()
{
//could wrap the logic inside a private member if the
constructor code would be shared...
shared_ptr<someclass> shptr(new someclass());
mem_shared_ptr = shptr;
//GrabAResource();
try{
OpenConnToDB();
}catch(...) //whatever specific exception catch
{
//ReleaseAResource();
}
}


The above constructor is exception safe now. If new someclass fails-
either through bad_alloc or any other exception from its own or its
base or any other member's constructor - or even if GrabAResurce()
fails then the code does not leak and that exception can be let to
pass through for the caller to handle it as appropriate. If
OpenConnToDB fails, the shared_ptr makes you not worry about it. But
the resource might need some attention if it is not RAII based. You
call a release for it in the handler. What do you not like about it?
It is exception safe, it is clear code and it is maintainable. (you
may have some refactoring into smaller functions if it makes the
constructor look more cluttered). Note that the important point is -
can the user want to have all these tasks done in the constructor? It
may not be - then you need to change but still this is a better design
if users need not much worry about constructors.


####
the constructor above is now not throwing an exception, which is fine
by me. maybe you meant that the catch hould be rethrown after cleanup.
I am not saying you should not have individual member to take up
those
individual bulkier tasks - but I am saying there is nothing wrong as
far as exception safety is concerned. If you are calling something as
*Initialization* - in an objects lifetime - that should happened once
- and while construction of the object. If want to allow user to
change something - that is not initialization. The user can have
option to close()/open() DB connection, can have option to grab()/
release() resource etc. but that depends on if the user needs it or
needs to know about it. Taking up a connection to the DB is an
intensive task - it might be opted to not take up a connection by
default and have the caller make an explicit call for it. But those
are different design points which are not related to exception safety.


###
I understand your viewpoint, I just think - at least for me personally
- that it is more clear when a class ctor doesn't throw an exception.
Conceptually since the object then never really exists and making
error handling clearer for a user of the class. By embedding/hiding a
lot of functionality in the ctor it is not that clear i.e. same as
having functions that are too complex doing too many things at one
time.

/ajk




.



Relevant Pages

  • No GUIs in cronstructors?
    ... exception or otherwise allow one to fly from inside the constructor, ... An Applet instance will ask for a Session class from the static ... The Connection constructor just creates a Socket and ...
    (comp.lang.java.programmer)
  • Re: is such exception handling approach good?
    ... There is nothing wrong with throwing from constructor. ... It may be a good design, it may not be a good design from user's point ... resource API to free-up the resource on exception. ... change something - that is not initialization. ...
    (microsoft.public.vc.language)
  • Re: The origins of CL conditions system
    ... Machine experience explaining the Lisp Machine error handling. ... languages with continuable exceptions (including Mary Fontana from TI ... Why can't I resume after catching an exception? ... exception handling chapter of The Design and Evolution of C++. ...
    (comp.lang.lisp)
  • RE: inheritance trouble - how to detect run-time or design-time in code
    ... The base class will throw a exception its ... VS.NET's design view again, yes? ... However, as for the Constructor, we're unable to use the above means to ... Move the code into page's OnInit method and use the ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: exiting a constructor early
    ... the exception object, and to 're-throw' a different object if you ... the body of the constructor - the handler is for handling the ... exception object - the constructor body need not do it. ... | at your design and ask yourself why that is the case. ...
    (alt.comp.lang.learn.c-cpp)

Loading