C++ 嵌套捕获运算符

C++ 嵌套捕获运算符,c++,exception,C++,Exception,我需要捕获可能由try…catch构造中的代码引发的异常,并根据异常类型执行某些操作。但如果抛出任何异常,我还想编写一些代码。 我这样做了: try { // code } catch (...) { try { throw; } catch (exc1) { // handling } catch (exc2) { // handling } // here

我需要捕获可能由try…catch构造中的代码引发的异常,并根据异常类型执行某些操作。但如果抛出任何异常,我还想编写一些代码。 我这样做了:

try
{
    // code
}
catch (...)
{
    try
    {
        throw;
    }
    catch (exc1)
    {
        // handling
    }
    catch (exc2)
    {
        // handling
    }
    // here is code that are executed if any exception are thrown
}
我的代码是有效的,但我想知道标准是否对此有所说明。 也许有更好的方法吗

UPD:很抱歉回复评论太慢。简单地说,英语是我的第二语言


UPD:我认为阿德尼克的代码或史蒂夫·杰索普的第二个代码或大卫·罗德里格斯-德里比的第二个代码对我来说是正确的。

你的方法很糟糕,因为
//这里是在抛出任何异常时执行的代码
如果
exc1
exc2
分支都没有捕获到异常,则不会执行部分。您的代码是以下代码的等效版本:

try
{
    // code
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
// here is code that are executed if any exception are thrown
try
{
    try
    {
      // code
    }
    catch (exc1)
    {
        // handling
        throw; // edited. was: throw exc1;
    }
    catch (exc2)
    {
        // handling
        throw; // edited. was: throw exc2;
    }
} 
catch(...)
{
    // here is code that are executed if any exception are thrown
}

C++
语言不支持finally块,如果您想要的是finally块的话。这是因为对象的析构函数负责释放资源,而不是finally块。以下是主题。

您的方法不好,因为
//这里是在抛出任何异常时执行的代码。
如果
exc1
exc2
分支都没有捕获到异常,则不会执行部分。您的代码是以下代码的等效版本:

try
{
    // code
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
// here is code that are executed if any exception are thrown
try
{
    try
    {
      // code
    }
    catch (exc1)
    {
        // handling
        throw; // edited. was: throw exc1;
    }
    catch (exc2)
    {
        // handling
        throw; // edited. was: throw exc2;
    }
} 
catch(...)
{
    // here is code that are executed if any exception are thrown
}
C++
语言不支持finally块,如果您想要的是finally块的话。这是因为对象的析构函数负责释放资源,而不是finally块。以下是主题的摘要。

你应该写:

try
{
    // code
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
catch (...) 
{
    // here is code that are executed if any *other* exception are thrown
}
如果您希望将特定代码作为所有三种情况的一部分执行,那么您有两种选择:在所有三个位置调用它,或者执行类似以下操作:

bool threw = true;
try
{
    // code
    threw = false;
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
catch (...) {
}
if (threw) {
    // here is code that are executed if any exception are thrown
}
你应该写:

try
{
    // code
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
catch (...) 
{
    // here is code that are executed if any *other* exception are thrown
}
如果您希望将特定代码作为所有三种情况的一部分执行,那么您有两种选择:在所有三个位置调用它,或者执行类似以下操作:

bool threw = true;
try
{
    // code
    threw = false;
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
catch (...) {
}
if (threw) {
    // here is code that are executed if any exception are thrown
}

我将更改代码顺序如下:

try
{
    // code
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
// here is code that are executed if any exception are thrown
try
{
    try
    {
      // code
    }
    catch (exc1)
    {
        // handling
        throw; // edited. was: throw exc1;
    }
    catch (exc2)
    {
        // handling
        throw; // edited. was: throw exc2;
    }
} 
catch(...)
{
    // here is code that are executed if any exception are thrown
}

如果抛出任何其他类型的异常(不仅是exc1exc2),它也会起作用。此外,如果所有异常的代码都是资源释放,则考虑使用“原则”。

< P>我将更改代码顺序如下:

try
{
    // code
}
catch (exc1)
{
    // handling
}
catch (exc2)
{
    // handling
}
// here is code that are executed if any exception are thrown
try
{
    try
    {
      // code
    }
    catch (exc1)
    {
        // handling
        throw; // edited. was: throw exc1;
    }
    catch (exc2)
    {
        // handling
        throw; // edited. was: throw exc2;
    }
} 
catch(...)
{
    // here is code that are executed if any exception are thrown
}

如果抛出任何其他类型的异常(不仅是exc1exc2),它也会起作用。同样,如果所有例外的代码都是资源释放,则考虑使用原则来代替。

< P>查看评论,看起来你可能在期待一些不会发生的事情,并且已经在其他的答案中讨论过。但这可能是我们方面的误解。如果
try
中的代码只能抛出
exc1
exc2
中的一个,则是,它将执行您期望的操作


从注释更新来看,其目的似乎是处理任何异常,包括既不是
exc1
也不是
exc2
的异常。为此,代码不会执行预期的操作,
exc3
将在嵌套的
try
s之外传播。只需将两个级别展平,并在末尾添加一个
catch(…)


从这里开始,答案是基于对这个问题的错误假设

该标准支持重新刷新模式,通常用于不同上下文中异常处理相同的情况,以避免代码重复:

void processException() {
   // implement exception handling in all contexts
   try {
     throw;
   } catch (exceptionType1 const & ex1) {
   } catch (exceptionType2 const & ex2) {
// } catch (...) {
   }
}
void f() {
   try {
      something();
   } catch (...) {
      processException();
   }
}
void g() {
   try {
      anotherThing();
   } catch (...) {
      processException();
   }
}
如果处理异常的代码不会集中用于不同的函数,那么这种模式可能会使代码变得比您需要的更复杂。你可以考虑一个额外的控制变量:
bool success = false;
try {
   doSomething();
   success = true;
} catch (exception1 const & ex1) {
...
} catch (exception2 const & ex2) {
...
// } catch (...) {
}
if (!success) {
   // common code to all exceptions
}

看看这些评论,你似乎期待着一些不会发生的事情,这已经在其他答案中讨论过了。但这可能是我们方面的误解。如果
try
中的代码只能抛出
exc1
exc2
中的一个,则是,它将执行您期望的操作


从注释更新来看,其目的似乎是处理任何异常,包括既不是
exc1
也不是
exc2
的异常。为此,代码不会执行预期的操作,
exc3
将在嵌套的
try
s之外传播。只需将两个级别展平,并在末尾添加一个
catch(…)


从这里开始,答案是基于对这个问题的错误假设

该标准支持重新刷新模式,通常用于不同上下文中异常处理相同的情况,以避免代码重复:

void processException() {
   // implement exception handling in all contexts
   try {
     throw;
   } catch (exceptionType1 const & ex1) {
   } catch (exceptionType2 const & ex2) {
// } catch (...) {
   }
}
void f() {
   try {
      something();
   } catch (...) {
      processException();
   }
}
void g() {
   try {
      anotherThing();
   } catch (...) {
      processException();
   }
}
如果处理异常的代码不会集中用于不同的函数,那么这种模式可能会使代码变得比您需要的更复杂。你可以考虑一个额外的控制变量:
bool success = false;
try {
   doSomething();
   success = true;
} catch (exception1 const & ex1) {
...
} catch (exception2 const & ex2) {
...
// } catch (...) {
}
if (!success) {
   // common code to all exceptions
}

“我的代码是有效的”——这是怎么回事?如果异常既不是
exc1
也不是
exc2
,则不会执行“如果引发任何异常,则执行以下代码”。如果引发任何异常,则执行是什么意思?只有
exc1
exc2
?有什么例外吗?任何不属于
exc1
exc2
的例外情况?@DavidRodríguez dribea都是例外情况。“我的代码有效”——如何?如果异常既不是
exc1
也不是
exc2
,则不会执行“如果引发任何异常,则执行以下代码”。如果引发任何异常,则执行是什么意思?只有
exc1
exc2
?有什么例外吗?任何不属于
exc1
exc2
?@DavidRodríguez dribea的异常都是任何异常。
抛出exc在异常处理程序中是错误的做法,因为它会分割异常对象。如果您想重新抛出异常,只需执行
throw取决于如果代码为“han”时要执行的操作