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

问题:如果函数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_allocexception caught outside the constructor: std::bad_alloc
在我看来,无论我在函数try块中做什么,异常总是会被抛出到调用构造函数的外部范围,例如上面代码中的X x;

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

最佳答案

没错,异常总是传播的。

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

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

对于构造函数:

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

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

09-05 07:18