为什么我们需要一个函数try块
Why do we need a function try block?
这是帖子的后续问题。有关"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;
。
"function try block"的定义,摘自《c++ Primer 5》。
要处理构造函数初始化式的异常,必须将构造函数写成函数try块。函数try块允许我们将一组catch子句与构造函数的初始化阶段(或析构函数的析构阶段)以及构造函数(或析构函数)的函数体关联起来。
你是对的,异常总是被传播。
函数try块使你能够捕获异常,例如销毁作为参数传递的对象(可能这是一个智能指针类?),而无需引入人工基类。
更一般地说,它使您能够清除由函数调用引入的状态更改。
对于构造函数:
异常传播对所有成功构造的子对象调用析构函数,包括基类子对象(如果有的话)。但是,不调用这个未完全构造的对象自己的析构函数。理想情况下,函数try块不是用来做析构函数中应该做的事情的设备。未完全创建的对象自己的析构函数不需要做任何事情,因为它的任务是清理构造函数体和/或后来的成员函数调用引入的状态更改,并且根据常见的"零规则"设计,还没有这样的事情。
当构造函数抛出时,相应的析构函数不会运行。这就是书中引用的原因:清理必须由构造函数自己完成。
但是您的示例显示异常传播。这是必要的,因为构造函数失败了,因此没有创建对象。调用代码不应该像构造函数创建了一个对象那样进行。
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何仅为一个函数添加延迟
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 我需要将多个函数组合为一个函数
- 在C++中声明一个函数时,它需要有函数本身的参数吗
- 如何创建一个函数来计算并返回平均值、最大值和最小值
- 一个函数,用于查找字符串1包含字符串2 c++的次数
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- 编写一个函数以使用 n 百分比的 CPU 使用率
- 将 N-arg 函数包装到另一个函数中
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- C++从另一个函数退出函数
- 编写一个函数来删除单链表中的节点(尾部除外),仅授予对该节点的访问权限
- 视觉我希望一个函数在另一个函数C++中进行计算
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 在另一个函数 (c++) 中调用变量
- 如何在另一个函数中使用返回值作为参数?
- 如何包装一个函数以适应另一个函数的所需类型
- 创建一个函数的 Python 绑定,返回指向带有 boost 的向量的指针