繁体   English   中英

为什么我们需要一个功能try块?

[英]Why do we need a function try block?

这是该职位的后续问题。 请参阅此问题的末尾,以获取“功能尝试块”的定义。

问题:如果一个函数try块没有“处理”构造函数中引发的异常,为什么我们最终需要它们? 您能否举一个利用功能try块的示例?

考虑以下代码。

#include <iostream>
#include <new>  
#include <exception>
using namespace std;

struct X {
  int *p;
  X() try : p(new int[10000000000]) {}
  catch (bad_alloc &e) {
    cerr << "exception caught in the constructor: " << e.what() << endl;
  }
};

int main() {
  try {
    X x;
  }
  catch (exception &e){
    cerr << "exception caught outside the constructor: " << e.what() << endl;
  }
  return 0;
}

输出是

exception caught in the constructor: std::bad_alloc exception caught outside the constructor: std::bad_alloc

在我看来,无论我在函数try块中做什么,异常总是会被抛出到调用构造函数的外部范围,例如X x; 在上面的代码中。

“功能尝试块”的定义,摘录自“ C ++ Primer 5th”。

要处理构造函数初始化程序的异常,我们必须将构造函数编写为try块。 函数try块使我们可以将一组catch子句与构造函数的初始化阶段(或析构函数的销毁阶段)以及构造函数的(或析构函数的)函数体相关联。

没错,该异常总是会传播。

使用try块功能可以捕获该异常,例如销毁作为参数传递的对象(也许这是一个智能指针类?),而无需引入人工的基类。

更一般而言,它使您能够清除由函数调用引起的状态更改。


对于构造函数:

除了例外,将为所有成功构造的子对象(包括基类子对象(如果有))调用传播析构函数。

但是,不会调用此未完全构造的对象自己的析构函数。 理想情况下,功能try块不是用于执行该析构函数中的工作的设备。 未完成创建的对象自己的析构函数无关,因为它的任务是清理构造函数主体和/或以后的成员函数调用引入的状态更改,并且采用通用的“零规则”设计,因此没有然而。

当构造函数引发时,相应的析构函数不会运行。 这就是在您的书中引用的原因:清理必须由构造函数本身完成。

但是您的示例显示了异常传播。 这是必需的,因为构造函数失败了,因此没有创建对象。 调用代码不应像构造函数创建对象一样继续进行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM