new []/delete []并在C++中抛出构造函数/析构函数

Dan*_*ica 1 c++ arrays exception new-operator delete-operator

在下面的代码中,如果构造/销毁某些数组元素会发生什么?

X* x = new X[10]; // (1)
delete[] x;       // (2)
Run Code Online (Sandbox Code Playgroud)

我知道可以防止内存泄漏,但另外:

  1. Ad(1),先前构造的元素是否被破坏?如果是,如果析构函数抛出这种情况会发生什么?

  2. 广告(2),是否破坏了尚未被破坏的元素?如果是,如果析构函数再次抛出会发生什么?

Use*_*ess 5

  1. 是的,如果是x[5]throws 的构造函数,那么x[0]..x[4]已经成功构造的五个数组元素将被正确销毁.

    • 析构者不应该抛出.如果析构函数抛出,则会在仍处理上一个(构造函数)异常时发生这种情况.由于不支持嵌套异常,因此std::terminate会立即调用.这就是析构师不应该抛出的原因.
  2. 这里有两个互斥的选项:

    1. 如果你达到标签(2),构造函数就不会抛出.也就是说,如果x成功创建,则成功构建了所有十个元素.在这种情况下,是的,它们都被删除了.不,你的析构函数仍然不应该抛出.

    2. 如果构造函数通过步骤部分抛出(1),那么数组x 从未真正存在过.该语言尝试为您创建它,失败并抛出异常 - 因此您根本无法访问(2).

要理解的关键是x要么存在 - 在一个理智和可预测的状态 - 或者它不存在.

如果构造函数失败,该语言不会给你一些不可用的半初始化的东西,因为你无论如何也无法对它做任何事情.(你甚至无法安全地删除它,因为无法跟踪哪些元素被构造,哪些只是随机垃圾).

将数组视为具有十个数据成员的对象可能会有所帮助.如果您正在构造此类的实例,并且其中一个基类或成员构造函数抛出,则所有先前构造的基础和成员将以完全相同的方式销毁,并且您的对象永远不会开始存在.