构造函数中的异常:init() 方法、指针、大型 try/catch 或

Exception in constructor: init() method, pointers, large try/catch or..?

本文关键字:大型 指针 try catch 方法 异常 init 构造函数      更新时间:2023-10-16

我正在处理一个可能引发错误的对象构造函数。我有以下选择。

1(有一个非常大的try块,它包含了所有需要对象的代码(因为对象范围(:

try {
  Object a(input_vars); // This can throw
  // Do 
  // loads of stuff 
  // with a here
} catch (exception e) {
  // Do something with exception    
}

我对此不是特别满意,因为它将包含一个非常大的代码部分。不过,也许是这里最吸引人的选择。

2( 将抛出移动到 init(( 方法:

Object a(input_vars); // This one does not throw
try {
  a.init(); // Only this one can throw
} catch (exception e) {
  // Do something with exception (EDIT: and terminate)
}
// Do some stuff with a

但是,这会导致对象被半构造,要求人们记住调用 init((,并违反资源获取即初始化 (RAII(。

3( 仅使用指针:

Object* a;
try {
  a = new Object(input_vars); // This one can throw
} catch (exception e) {
  // Do something with exception (EDIT: and terminate)
}
// Do some stuff with a
delete a;

这需要记住销毁对象。它还增加了悬垂指针等的风险。

您更喜欢上述哪一个选项,出于什么原因?还有其他我没有考虑过的选择吗?

选项 1( 是正确的。原因:当构造函数抛出时,对象a构造失败,因此不存在任何有效状态。以下使用 a 的代码要么必须始终编写以考虑这种可能性,要么最好完全跳过它。