Re: is such exception handling approach good?



"ajk" wrote:
Say if a class initializes some memory, grabs some
resource and opens
an oracle database in the ctor then what should you do
with the object
if one of those three failed?

It depends on the nature of a class. Sometimes I need none
of them in constructor; sometimes all of them.

The main purpose to do this in constructor is exactly in
order to avoid undefined state of the object. When you
construct it in phases, then complexity of class members
increases insanely. You just can't trust yourself inside
class memeber anymore and bound to perform tedious error
prone checks for everything. It harms both performance and
stability of the code, not to mention high maintenance
costs.

Suppose you have the class:

class AllInOne
{
...

private:
BYTE* m_pBuf;
DBConn* m_pConn;
FILE* m_fLog;
};

Now you have two options:

1. Establish defined state of the object in constructor:

AllInOne::AllInOne() :
m_pBuff(new BYTE[42]),
m_pConn(OpenDB(...))
m_fLog(fopen(...))
{
// do other stuff
}

Then you can reliably use its methods:

BYTE AllInOne::GetData(int i)
{
return m_pBuff[i];
}

void AllInOne::RetrieveData()
{
m_pConn->FillBuff(m_pBuff, 42);
}

etc.

2. Create "simple" object first, then create necessary part
separately:

AllInOne::AllInOne() :
m_pBuff(NULL),
m_pConn(NULL)
m_fLog(NULL)
{
}

AllInOne::InitBuff()
{
if(!m_pBuff)
m_pBuff = new BYTE[42];
else
assert("Cannot init the buffer twice!");
}

AllInOne::InitDBConn()
{
if(!m_pConn)
m_pConn = OpenDB(...);
else
assert("Cannot init DB twice!");
}

etc.

Now all of class' methods must paranoicaly check internal
state and hope for the best that user won't forget to call
relevant initializer functions:

BYTE AllInOne::GetData(int i)
{
if(m_pBuff)
return m_pBuff[i];
else
// deal with error
}

void AllInOne::RetrieveData()
{
if(m_pConn)
{
if(m_pBuff)
m_pConn->FillBuff(m_pBuff, 42);
else
// deal with error
}
else
{
// deal with error
}
}


In my other reply I posted a link to the excerpt from
Strostrup's TC++PL. He discusses the topic in details there.

Alex


.



Relevant Pages

  • Re: Convenience constructors and non-final setters
    ... comfort severely (ok, I guess that argument doesn't count for OO-purists), ... init() method which would have been called before setSeed. ... constructor runs, initruns, setSeedruns, and the subclass ... In my opinion they should have made Random abstract, ...
    (comp.lang.java.programmer)
  • Re: All those constructors...
    ... > I have this fairly large class heirarchy, ... creating package visible setXXX() for the init parameters ... creating a public init() method which subclasses use for their constructor ...
    (comp.lang.java.programmer)
  • Re: is such exception handling approach good?
    ... "Alex Blekhman" wrote: ... of them in constructor; sometimes all of them. ... void AllInOne::RetrieveData ... assert("Cannot init the buffer twice!"); ...
    (microsoft.public.vc.language)
  • Re: Remoting service wont start
    ... I often see those kinds of errors in services because of things like syntax errors in the App.config file, or in the constructor, or on init. ... Does anyone know what might be causing it? ...
    (microsoft.public.dotnet.general)
  • Re: trying to call a virtual method from constructor of abstract object
    ... >> I guess it's obvious that the constructor of CObject can't see the ... >> classes definition of init, but I want any derived object to call ... >> it to derived concrete classes is not really a solution. ...
    (alt.comp.lang.learn.c-cpp)