I've been looking at some code I'm working on, and we have the equivalent of this:
AutoPtr<A> x;
...
/// x gets initialized
...
B* y = new B(x.Detach());
Where AutoPtr is our version of auto_ptr, and Detach() returns the owned pointer and resets itself. Also, B() takes ownership of x.
Now, I realized that this will leak x if new throws an std::bad_alloc, so I changed the code to this:
AutoPtr<A> x;
...
/// x gets initialized
...
B* y = new B(x.Get());
x.Detach();
But then I realized that if B() 'owns' the pointer, and an exception happens during its construction, it should take care of deleting the parameter itself (or should it?), so the x will get deleted twice, once by B(), and once by x's destructor.
Now, is there a C++ idiom that gets around this problem, for example, making code that calls constructors responsible for cleaning up parameters? Most code I've seen doesn't seem to do that...
The obvious solution seems to be to pass a temporary
AutoPtr<A>
to the constructor ofB
:(this also adds resource control for the
B*
returned fromnew B()
).B
's constructor would just callx.Detach()
to initialize whatever it needs to initialize with theA*
. If an exception occurs at any point, theAutoPtr<A>
will release the object.If you want to retain the
A
object managed byx
in case of an exception, you can pass aAutoPtr<A>&
to the constructor ofB
instead.