在C++中初始化动态数组的正确方法

mef*_*fiX 7 c++ new-operator

我目前正在开发一个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)

然后调用构造函数,对吧?

sha*_*oth 7

你应该让std::bad_alloc传播 - 无论如何你可能没有任何合理的做法.

首先,从构造函数中抛出异常是发出问题信号的唯一可靠方法 - 如果没有异常则意味着对象是完全构造的.因此std::bad_alloc单独捕捉无助于抵御其他可能的例外情况.

那么你可以做些什么来"处理"它,以便其他代码知道并且可以做出适当的反应?

正确使用例外 - 让它们传播到可以合理处理的网站.


jal*_*alf 5

构造函数的整个目的是构造一个对象.这包括初始化.当构造函数完成执行时,该对象应该可以使用了.这意味着构造函数应该执行任何必要的初始化.

你的朋友建议你导致无法维护和容易出错的代码,并违背每一个优秀的C++实践.他错了.

至于动态数组,请std::vector改用.要初始化它,只需将参数传递给构造函数:

std::vector<int>(10, 20)
Run Code Online (Sandbox Code Playgroud)

将创建一个10个整数的向量,所有这些都初始化为值20.