首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我们需要一个函数试块?

为什么我们需要一个函数试块?
EN

Stack Overflow用户
提问于 2014-05-20 07:45:58
回答 2查看 272关注 0票数 2

这是post的后续问题.有关“函数尝试块”的定义,请参阅此问题的结尾。

问题:如果函数try块不“处理”构造函数中引发的异常,那么我们为什么需要它们呢?你能给出一个利用函数尝试块的例子吗?

考虑到下面的代码。

代码语言:javascript
运行
复制
#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 5“。

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

EN

回答 2

Stack Overflow用户

发布于 2014-05-20 07:50:02

你说得对,异常总是会被传播。

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

更广泛地说,它使您能够清理由函数调用引入的状态更改。

对于构造函数的情况:

对于所有成功构造的子对象,包括基类子对象(如果有的话),都会调用传播析构函数。

但是,不调用未完全构造的对象本身的析构函数。理想情况下,函数try块不是用于执行该析构函数中的操作的设备。未完全创建的对象本身的析构函数与此无关,因为它的任务是清理构造函数主体和/或以后的成员函数调用所引入的状态更改,并且使用常见的“零规则”设计,目前还没有这样的设计。

票数 3
EN

Stack Overflow用户

发布于 2014-05-20 07:51:51

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23753821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档