【问题标题】:Exception in constructor: init() method, pointers, large try/catch or..?构造函数中的异常:init() 方法、指针、大型 try/catch 或..?
【发布时间】:2018-07-13 01:23:26
【问题描述】:

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

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) 将 throw 移至 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;

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

您更喜欢上述哪个选项?出于什么原因?还有其他我没有想到的选择吗?

【问题讨论】:

  • 如果我是正确的,第三个不是悬空指针,而是内存泄漏,因为在newthrow 之后内存没有被释放。
  • 2 和 3 都让您对未能构造的对象“做一些事情”,因此 不存在(无论如何都处于可用状态)。您希望该代码如何处理它?
  • @Quentin 够公平的。在我看来,异常总是会退出程序。我现在意识到这有点愚蠢..
  • @GoverNator 是的,在您发布之前更正了几秒 :)
  • 如果您对在 try 中包含大量代码不是特别满意,请将其放在以 Object 作为参数的函数中

标签: c++ exception constructor


【解决方案1】:

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

【讨论】:

  • +1。为了避免代码中的 cmets 提示“在这里使用a 做很多事情”的问题,编写另一个函数并从try 块内部调用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
相关资源
最近更新 更多