Re: Exceptions & Constructors
Xavier Serrand wrote:
"tragomaskhalos" <dave.du.vergier@logicacmg.com> a ?crit dans le message
de news:1185829800.622009.116710@q75g2000hsh.googlegroups.com...
On 30 Jul, 19:50, "Xavier Serrand" <xxxxxx.xxxx...@xxx.fr> wrote:
template <typename T> static Pile<T> * createPile(int sz)
{
Pile<T> * pp;
try
{
pp = new Pile<T>(sz);
return pp;
}
catch (std::bad_alloc&)
{
try
{
// clearing what can be cleared ...
// ...
// deleting the instance : the destructor has to be sure
// (may be hard to do...)
pp->~Pile<T>();
}
catch (std::exception& e)
{
// nothing to do
}
return NULL;
}
}
This is wrong isn't it? If bad_alloc is thrown then
the object won't have been constructed, so you don't
want to be calling the destructor on 'pp' - UB and
all that (not to mention the fact that pp is
uninitialised in this case anyway). In any case,
using new(nothrow) saves you having to mess about
with bad_alloc in the first place.
But as Alf has pointed out it's all largely academic,
if your program reaches this point you're probably
scuppered anyway, which reinforces my earlier
suggestion of keeping it simple and just letting the
exception propagate out of the ctor.
object could hav been constructed and bad_alloc raised ... after if one or
more members are pointers
[snip]
No.
If during evaluation of the expression
new SomeType ( some args )
memory allocation is successful but the constructor call throws (whatever it
may throw) the call to new will not return, the memory will be deallocated
and not leak, and there will not be possible way to do manual clean up
afterwards. For example, in the code above, if
pp = new File<T>( sz )
throws from the call to File<T>, the variable pp will not point to anything
meaningful. In particular, pp->~File<T>() is undefined behavior.
The upshot is: you have to write the constructor for any class in such a way
that it does not leak when subobjects and members cannot be successfully
constructed. Outside the constructor, there is no way to undo the harm that
has been done. In the above example, if File<T>() could fail, it better
fail gracefully (without resource leak) because your proposed trick to
repair things from the outside is bound to fail.
Hint: within constructors, use std::auto_ptr for allocation of multiple
pointer members.
Best
Kai-Uwe Bux