Reputation: 1151
When a bad_alloc
exception is thrown in a constructor, in which multiple objects are created, what must be done to clean up the memory. Ex.
class Object
{
private:
A * a;
B * b;
public:
Object()
{
a= new A();
b= new B(); //So if a bad_alloc is called here, how is a deleted???
}
}
My intuition is to place each call to new in a separate try catch bloc, and delete all objects for which new
was called previously but this is too verbose (the first try bloc calls no destructor, the second class that of the first, the 3rd calls that of the first two etc). My question is: What is the most common way to handle this?
Also, lets say the class objects contains a object not created with new (because it is on the stack), is its destructor called automatically?
Upvotes: 1
Views: 2861
Reputation: 31445
Firstly I fixed your code because it is a C++ question, so it has to be written as C++. A constructor might fail with exceptions other than bad_alloc.
Your options are there:
Do not store pointers but store the objects. These are constructed automatically (or via the initialiser list) and yes will automatically be cleaned up if created. This can be better but means they need to be fully defined, i.e. their headers included, and you may be trying to hide your implementation detail / decouple..
Store some kind of smart pointer like unique_ptr
which is really an object so gets cleaned up like an object, deleting the underlying pointer if there is one.
Store a regular pointer in your class but use unique_ptr
(or auto_ptr
if unique_ptr
is not available) during the constructor and, at the end when you know everything has constructed properly, you can release your smart pointers into your member variables.
The latter solution would look like:
// header file
//
class A; // implementation hidden on purpose
class B; // ditto
class Object
{
private:
A * a;
B * b;
public:
Object();
~Object();
private:
// if not using C++11 do not put in =delete but still declare these
Object( const Object & ) = delete;
Object& operator=( const Object & ) = delete;
};
// cpp file
#include "object.h"
#include "a.h"
#include "b.h"
Object::Object()
: a( nullptr ), // use NULL or 0 if nullptr not available
b( nullptr )
{
std::unique_ptr< A > pa( new A ); // might throw
std::unique_ptr< B > pb( new B ); // might throw (1)
a = pa.release(); // cannot throw
b = pb.release();
}
Object::~Object()
{
delete b;
delete a;
}
(1) if it throws pa
which is local will have its destructor invoked which will delete the pointer you created with new.
Note: if you don't have unique_ptr
available, auto_ptr
will serve just as well here.
Upvotes: 2
Reputation: 27577
You want to use smart pointers:
class Object {
std::unique_ptr<A> a;
std::unique_ptr<B> b;
public:
Object() : a(make_unique<A>()), b(make_unique<B>()) {}
}
Upvotes: 6