in the contructor of x we are not considering the scenation "if the memory allocation fails" .
You don't have to. If it fails, the constructor will throw std::bad_alloc
. I.e.:
- Y constructor is called.
- X constructor is called.
- The
new int[]
allocation fails, throwing std::bad_alloc
. The memory is never allocated.
- Because X never finished constructing, the Y constructor fails and Y never finishes constructing either.
Therefore there are no leaks.
Here for the destructor of Y is safe as in y construcotr is not allocating any memory. what if we need to do some memory allocation also in y constructor?
You still have no problem. Allocation failures will throw std::bad_alloc
. That failure is the responsibility of those using your class.
- Y constructor is called.
- X constructor is called.
- The
new int[]
allocation succeeds.
- The Y constructor now fails somehow and needs to throw an exception (for example an allocation failure).
- The exception throwing mechanism unwinds the call stack and calls destructors on any local variables, in this case including X.
- X's destructor
delete[]
s the new int[]
.
Again, no resources are leaked here.
Note that you do need to be wary of multiple allocations. I.e.:
class Foo
{
int * r;
public:
Foo() {
r = new int;
throw myException;
};
~Foo() {
delete r;
};
};
NOW we have a resource leak. When the exception is thrown from the constructor, the object is never fully constructed. Since it's never fully constructed, it's never going to have it's destructor called. Therefore we leak r
.