我目前正在开发一个C++项目,其中经常出现动态数组.我想知道,使用new-operator初始化动态数组的正确方法是什么?我的一位同事告诉我,在构造函数中使用new是一个禁忌,因为构造函数是一个不应该容易出错或者根本不应该失败的构造.现在让我们考虑以下示例:我们有两个类,一个或多或少复杂的类State和一个StateContainer类,应该自我解释.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,我有两个问题:
1.)是否可以在构造函数中调用new,或者更好的是创建一个额外的init() - State-Array的方法以及为什么?
2.)什么是检查新成功的最佳方法:
if (!ptr) std::cerr << "new failed."
Run Code Online (Sandbox Code Playgroud)
要么
try { /*new*/ } catch (std::bad_alloc) { /*handling*/ }
Run Code Online (Sandbox Code Playgroud)
3.)好了它的三个问题; o)在引擎盖下,新的确有某些问题
ptr = (Struct *)malloc(N*sizeof(Struct));
Run Code Online (Sandbox Code Playgroud)
然后调用构造函数,对吧?
你应该让std::bad_alloc传播 - 无论如何你可能没有任何合理的做法.
首先,从构造函数中抛出异常是发出问题信号的唯一可靠方法 - 如果没有异常则意味着对象是完全构造的.因此std::bad_alloc单独捕捉无助于抵御其他可能的例外情况.
那么你可以做些什么来"处理"它,以便其他代码知道并且可以做出适当的反应?
正确使用例外 - 让它们传播到可以合理处理的网站.
构造函数的整个目的是构造一个对象.这包括初始化.当构造函数完成执行时,该对象应该可以使用了.这意味着构造函数应该执行任何必要的初始化.
你的朋友建议你导致无法维护和容易出错的代码,并违背每一个优秀的C++实践.他错了.
至于动态数组,请std::vector改用.要初始化它,只需将参数传递给构造函数:
std::vector<int>(10, 20)
Run Code Online (Sandbox Code Playgroud)
将创建一个10个整数的向量,所有这些都初始化为值20.