为什么我们需要一个函数try块? [英] Why do we need a function try block?

查看:181
本文介绍了为什么我们需要一个函数try块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是的后续问题帖子。请问这个问题的结尾是否定义了function try block。



问题:如果函数try块没有处理异常提出在构造函数中,为什么我们需要它们?你可以举个例子来利用函数try块吗?



考虑以下代码。

  #include< iostream> 
#include< new>
#include< exception>
使用命名空间std;

struct X {
int * p;
X()try:p(new int [10000000000]){}
catch(bad_alloc& e){
cerr< 异常捕获在构造函数中:<< e.what()< ENDL;
}
};

int main(){
try {
X x;
}
catch(exception& e){
cerr<< 异常捕获在构造函数外面:<< e.what()< ENDL;
}
return 0;
}

输出是



异常捕获在构造函数中:std :: bad_alloc
异常在构造函数外部捕获:std :: bad_alloc



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



函数try块的定义,摘自C ++入门为了处理一个构造函数初始化器的异常,我们必须把构造函数写成一个函数try块。函数try块允许我们将一组catch子句与构造函数的初始化阶段(或析构函数的销毁阶段)以及构造函数(或析构函数)的函数体相关联。



解决方案

你是对的,异常总是传播。



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



更一般地,它可以让你清理调用函数引入的状态更改。






对于构造函数的情况:



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



但是,这个不完全构造的对象自己的析构函数不被调用。函数try块理想地不是用于执行那些析构函数的设备。不完全创建的对象自己的析构函数无关紧要,因为它的任务是清除由构造函数体引用的状态变化和/或后续成员函数调用,并且使用通用的零规则设计不存在而


This is a follow-up question of the post. Please see the end of this question for a definition of "function try block".

Question: If a function try block does not "handle" the exception raised in the constructor, why do we need them after all? Could you give an example taking advantage of function try block?

Considering the following code.

#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;
}

The output is

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

It seems to me that, no matter what I do in the function try block, the exception is always going to be thrown to the outer scope which calls the constructor, e.g. the X x; in the above code.

Definition of "function try block", excerpted from "C++ Primer 5th."

To handle an exception from a constructor initializer, we must write the constructor as a function try block. A function try block lets us associate a group of catch clauses with the initialization phase of a constructor (or the destruction phase of a destructor) as well as with the constructor’s (or destructor’s) function body.

解决方案

You're right that the exception is always propagated.

The function try block enables you to catch that exception and e.g. destroy an object passed as argument (maybe this is a smart pointer class?), without introducing an artificial base class.

More generally, it gives you the ability to clean up state changes introduced by the call of the function.


For the case of a constructor:

With the exception propagation destructors are called for all successfully constructed sub-objects, including base class sub-objects (if any).

However, this not completely constructed object's own destructor is not called. The function try block is ideally not a device for doing things that would go in that destructor. The not-completely-created object's own destructor has nothing to do, for its task is to clean up state changes introduced by the constructor body and/or later member function calls, and with a common "rule of zero" design there's no such as yet.

这篇关于为什么我们需要一个函数try块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆