在析构函数中正确使用std :: uncaught_exception [英] right usage of std::uncaught_exception in a destructor

查看:232
本文介绍了在析构函数中正确使用std :: uncaught_exception的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些文章总结出永远不会从析构函数中抛出异常,而std :: uncaught_exception()无效,例如:





但似乎我没有得到点。所以我写了一个小的测试示例(见下文)。



由于测试示例中的一切都很好,我将非常感谢有关可能出错的一些意见? / p>

测试结果:



./ main

 
Foo ::〜Foo():捕获异常 - 但有待处理的异常 - 忽略
int main(int,char **):捕获异常:从int Foo :: bar(int)

./ main 1

 
Foo: :〜Foo():捕获异常 - 但*否*异常正在等待 - 重新抛出
int main(int,char **):捕获的异常:从Foo ::〜Foo()

示例:

  //文件main.cpp 
//用eg make main
//在Ubuntu-Karmic上使用g ++ v4.4.1
#include< iostream>测试成功

class Foo {
public:

int bar(int i){
if(0 == i)
throw(std :: string(from)+ __PRETTY_FUNCTION__);
else
return i + 1;
}

〜Foo(){
bool exc_pending = std :: uncaught_exception();
try {
bar(0);
} catch(const std :: string& e){
//确保在此期间没有创建新的异常
if(std :: uncaught_exception())exc_pending = true ;

if(exc_pending){
std :: cerr < __PRETTY_FUNCTION__
<< :捕获异常 - 但有待处理的异常 - 忽略
<<的std :: ENDL;
} else {
std :: cerr<<< __PRETTY_FUNCTION__
<< :catch exception - but * no * exception is pending - rethrowing
<<的std :: ENDL;
throw(std :: string(from)+ __PRETTY_FUNCTION__);
}
}
}

};

int main(int argc,char ** argv){
try {
Foo f;
//将在Foo :: bar()中抛出异常,如果没有给出参数。否则
//抛出Foo ::〜Foo()的异常。
f.bar(argc-1);
} catch(const std :: string& e){
std :: cerr<< __PRETTY_FUNCTION__<< :catch exception:<< e<的std :: ENDL;
}
return 0;
}

ADDED :换句话说:某些文章中的警告可以按预期方式工作,所以可能会出错?

解决方案

您的代码没有什么技术上的错误。这是完全安全的,因为你不会意外终止,因为当你不安全时抛出异常。问题是它也没有用,因为它偶尔也不会在安全的时候抛出异常。您的析构函数的文档基本上必须说这可能或不会抛出异常。



如果偶尔不会抛出异常,那么你也可以永远不会抛出异常。这样,你至少是一致的。


There are some articles concluding "never throw an exception from a destructor", and "std::uncaught_exception() is not useful", for example:

But it seems that I am not getting the point. So I wrote a small testing example (see below).

Since everything is fine with the testing example I would very appreciate some comments regarding what might be wrong with it ?

testing results:

./main

    Foo::~Foo(): caught exception - but have pending exception - ignoring
    int main(int, char**): caught exception: from int Foo::bar(int)

./main 1

    Foo::~Foo(): caught exception -  but *no* exception is pending - rethrowing
    int main(int, char**): caught exception: from Foo::~Foo()

example:

// file main.cpp
// build with e.g. "make main"
// tested successfully on Ubuntu-Karmic with g++ v4.4.1
#include <iostream>

class Foo {
  public:

  int bar(int i) {
    if (0 == i)
      throw(std::string("from ") + __PRETTY_FUNCTION__);
    else
      return i+1;
  }

  ~Foo() {
    bool exc_pending=std::uncaught_exception();
    try {
      bar(0);
    } catch (const std::string &e) {
      // ensure that no new exception has been created in the meantime
      if (std::uncaught_exception()) exc_pending = true;

      if (exc_pending) {
        std::cerr << __PRETTY_FUNCTION__ 
                  << ": caught exception - but have pending exception - ignoring"
                  << std::endl;
      } else {
        std::cerr << __PRETTY_FUNCTION__
                  << ": caught exception -  but *no* exception is pending - rethrowing"
                  << std::endl;
        throw(std::string("from ") + __PRETTY_FUNCTION__);
      }
    }
  }

};

int main(int argc, char** argv) {
  try {
    Foo f;
    // will throw an exception in Foo::bar() if no arguments given. Otherwise
    // an exception from Foo::~Foo() is thrown.
    f.bar(argc-1);
  } catch (const std::string &e) {
    std::cerr << __PRETTY_FUNCTION__ << ": caught exception: " << e << std::endl;
  }
  return 0;
}

ADDED: In other words: despite of the warnings in some articles it works as expected - so what might be wrong with it?

解决方案

There's nothing technically wrong with your code. It's perfectly safe in that you will never accidentally terminate because you threw an exception when it was not safe to. The issue is that it also is not useful, in that it will occasionally also not throw an exception when it is safe to. Your destructor's documentation basically has to say "this might or might not throw an exception."

If it occasionally won't throw an exception, you might as well never throw an exception. That way, you're at least consistent.

这篇关于在析构函数中正确使用std :: uncaught_exception的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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