I'm currently working on a C++ project, where dynamic arrays often appear. I was wondering, what could be the correct way to initialize a dynamic array using the new-operator? A colleague of mine told me that it's a no-no to use new within the constructor, since a constructor is a construct that shouldn't be prone to errors or shouldn't fail at all, respectively. Now let's consider the following example: We have two classes, a more or less complex class State and a class StateContainer, which should be self-explained.
class State {
private:
unsigned smth;
public:
State();
State( unsigned s );
};
class StateContainer {
private:
unsigned long nStates;
State *states;
public:
StateContainer();
StateContainer( unsigned long n );
virtual ~StateContainer();
};
StateContainer::StateContainer() {
nStates = SOME_DEFINE_N_STATES;
states = new State[nStates];
if ( !states ) {
// Error handling
}
}
StateContainer::StateContainer( unsigned long n ) {
nStates = n;
try {
states = new State[nStates]
} catch ( std::bad_alloc &e ) {
// Error handling
}
}
StateContainer::~StateContainer() {
if ( states ) {
delete[] states;
states = 0;
}
}
Now actually, I have two questions:
1.) Is it ok, to call new within a constructor, or is it better to create an extra init()-Method for the State-Array and why?
2.) Whats the best way to check if new succeeded:
if (!ptr) std::cerr << "new failed."
or
try { /*new*/ } catch (std::bad_alloc) { /*handling*/ }
3.) Ok its three questions ;o) Under the hood, new does some sort of
ptr = (Struct *)malloc(N*sizeof(Struct));
And then call the constructor, right?
You should let the std::bad_alloc
propagate - there's likely nothing reasonable you could do anyway.
First of all, throwing an exception from the constructor is the only reliable way to signal a problem - if there's no exception it means the object is completely constructed. So catching std::bad_alloc
alone will not help against other possible exceptions.
Then what can you do to "handle" it in such a way that the other code is aware and can react appropriately?
Use exceptions right - let them propagate to the site where they can be reasonably handled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With