Early today I discovered function try-catch blocks (from here in fact) and then went on a bit of a research spree - apparently they're main use is it catch exceptions throw in by a constructor initialiser list.
Anyway, this sent me thinking about failing constructors and I've got to a stage where I just need a little clarification. This is all just me trying to learn more about the language, so I don't have a practical example, but here goes...
Given this example code:
class A
{
private:
B b
C *c; //classes B, C & D omitted for brevity as not really relevant
D d;
public
A(int x, int y, int z)
};
A::A(int x, int y, int z)
try
: b( x )
, c( new C(y) )
, d( z )
{
//omitted
}
catch(...)
{
//omitted
}
What happens in these cases:
- The initialisation of
b
throws an exception. - The initialisation of
c
throws an exception. - The initialisation of
d
throws an exception.
Specifically, I want to know at least:
- what will/may cause a memory leak from
new C(y)
. I'm thinking only 3? (see here) - could you just
delete b
in the catch? Is dangerous in cases 1 and 2?
Obviously, I guess the safest thing to do is to make c
a smart pointer. But disregarding that option for the moment, what's the best course of action?
Is it safe to set c
to NULL
in the initialiser, and then place the call to new
in the constructor body?
That would then mean a delete c
must be placed in the catch in case something else throws in the constructor body? Are there safety issues doing that (ie, if it's the c = new C(y);
itself that throws)?