C++ 在 try 块中创建对象,然后将它们存储在 std::array

C++ Create objects in a try bloc then store them in a std::array

我有一个 Player 对象,它可以在其构造函数中抛出异常,因此在我的主函数中,我在 try 块中创建了 2 个 Player 对象。 我想像这样将这 2 Player 存储在 std::array 中:

try
{
  Player p1(10, 10, ikazuchi);
  Player p2(70, 10, hibiki);
  std::array<Player, 2> players = {p1, p2};
}

问题是我无法在 try 块之外使用数组,而且我听说将所有 main 代码放在 try 块中通常不是一个好主意。

我无法在 try 块之后声明我的 std::array,因为 p1p2 不再存在。

我可以用 std::vector 解决问题,但我读到,当我在编译期间知道数组的大小时,最好使用 std::array

我可以创建一个默认构造函数来创建我的对象,然后将它们填充到 try 块中,但在构造函数中创建所有内容似乎更合适。

最佳做法是什么?

您可以执行如下操作。

int main() {
  std::array<int, 2> array;
  try {
    array[0]=1;
    array[1]=1;
  } catch (...) {
  }
  return 0;
}

使用Player代替int

您总是可以使用动态分配或 boost::optional<std::array<Player, 2>> 之类的方法来解决此类问题,但真正的问题是:您应该这样做吗?也就是说,假设其中一个玩家对象无法构造并抛出异常。之后你将如何处理 players 数组?它不处于合法状态,或者至少不处于您期望的状态(如果没有抛出异常)。

try 的范围大一点没有问题。它应该涵盖所有异常会阻止您前进的地方。如果您不喜欢物理上有很多源代码,请将代码移到一个函数中。无论如何,这可能是个好主意:一个假设一切顺利的函数,另一个主要负责处理错误的函数。

并且如果当内部对象处于无效状态(构造函数抛出)时您有继续使用 players 的有意义的方法,那么您可以首先创建包含处于该状态的对象的数组(在 try 块之外),只需在 try.

内部分配它们

问题表明您不想提供不需要的默认构造函数,但我声称 player 属于 try,或者 Player 需要默认构造函数(或表达“未正确初始化”的等效方式。

如果你的玩家 csn 是 copied/moved 并且构造简单,只需创建数组并分配给它。

std::array<Player, 2> players;
try{
  players[0]=Player(10, 10, ikazuchi);
  players[1]=Player(70, 10, hibiki);
} catch ...

或者你可以这样做:

std::optional<std::array<Player, 2>> players;
try{
  Player p1(10, 10, ikazuchi);
  Player p2(70, 10, hibiki);
  players.emplace(std::array<Player, 2>{{std::move(p1),std::move(p2)}});
} catch ...

但您可能需要找到非 C++17 版本的可选,例如 boost 可选。

另一种方法是:

auto players = [&]()->std::array<Player, 2>{
  try {
    Player p1(10, 10, ikazuchi);
    Player p2(70, 10, hibiki);
    return {{std::move(p1),std::move(p2)}};
  } catch (some_error){
    throw some_other_error;
  }
}();

但因此需要通过数组或抛出退出。