代码之家  ›  专栏  ›  技术社区  ›  Joshua Fox

在C++中,有两个字之间有区别吗?

  •  17
  • Joshua Fox  · 技术社区  · 15 年前

    我想问 this question (也) here ,但是这次是关于C++的。

    C++之间的区别是什么?

    try { /*some code here*/}
    catch(MyException& ex)
    { throw ex;} //not just throw
    

    try {  /*some code here*/}
    catch(MyException& ex)
    { throw;} //not throw ex
    

    只是在堆栈跟踪中(C++中的任何一个都不是C语言或Java中的标准)吗?

    (如果有什么不同,我会使用MSVs2008。)

    8 回复  |  直到 6 年前
        1
  •  31
  •   Joshua Fox    12 年前

    throw; 重新引发它在 throw ex; 引发新的异常。除了创建一个新的异常对象的性能原因之外,它不会有什么不同。如果您有一个异常层次结构,其中有一些其他的异常类派生自 MyException 当抛出异常时,您已经 throw DerivedClassException; 它可以被 catch(MyException&) . 现在,如果修改捕获的异常对象并使用 投掷; 异常对象的类型仍然是 DerivedClassException . 如果你这样做了 throw Ex; 对象切片发生,新引发的异常将为类型 原始的异常 .

        2
  •  14
  •   ephemient    15 年前

    [ C++ FAQ Lite § 17.9 ]做什么? throw; (在 throw 关键词)平均值?我在哪里使用它?

    您可能会看到类似这样的代码:

    class MyException {
    public:
      ...
      void addInfo(const std::string& info);
      ...
    };
    
    void f()
    {
      try {
        ...
      }
      catch (MyException& e) {
        e.addInfo("f() failed");
        throw;
      }
    }
    

    在本例中,语句 投掷; 表示“重新引发当前异常”。在此,函数捕获了异常(通过非常量引用),修改了异常(通过向其添加信息),然后重新引发异常。通过在程序的重要函数中添加适当的catch子句,可以使用这个习惯用法来实现简单的堆栈跟踪形式。

    另一个重新抛出的习惯用法是“异常调度程序”:

    void handleException()
    {
      try {
        throw;
      }
      catch (MyException& e) {
        ...code to handle MyException...
      }
      catch (YourException& e) {
        ...code to handle YourException...
      }
    }
    
    void f()
    {
      try {
        ...something that might throw...
      }
      catch (...) {
        handleException();
      }
    }
    

    这个成语只允许一个函数( handleException() )用于处理多个其他函数中的异常。

    [ C++ FAQ Lite § 17.11 ]当我抛出这个对象时,它将被复制多少次?

    视情况而定。可能是“零”。

    引发的对象必须具有可公开访问的复制构造函数。编译器可以生成任意次数(包括零次)复制抛出对象的代码。但是,即使编译器从未真正复制抛出的对象,它也必须确保异常类的复制构造函数存在并且可以访问。

    ( 为了更清楚地了解我认为显而易见的事情而编辑… )

    catch(MyException& ex) { throw ex; } 可以复制 ex 以及它所涉及的所有问题; catch(MyException& ex) { throw; } 可能不会。

        3
  •  12
  •   Managu    15 年前

    如果您有一个异常层次结构, throw ex 可以分割您的异常,而 throw 不会。例如:

    #include <iostream> 
    #include <string> 
    
    using namespace std; 
    
    struct base 
    { 
      virtual string who() {return "base";} 
    }; 
    
    struct derived : public base 
    { 
      string who() {return "derived";} 
    }; 
    
    int main() { 
      try { 
        try { 
          throw derived(); // throws a 'derived'
        }  
        catch (base& ex)  
        { 
          throw ex; // slices 'derived' object to be a 'base' object
        } 
      } 
      catch (base& ex) 
      { 
        cout<<ex.who()<<endl; // prints 'base'
      } 
    } 
    

    更改 投掷前 只是 ,您将得到 derived 这是你可能期望得到的。

        4
  •  5
  •   philsquared    15 年前

    你可以使用 throw; 形式与 catch(...) (也就是说,如果使用catch(…)捕获,它是重新引发的唯一方法)。

        5
  •  3
  •   Will_of_fire    6 年前

    有很大的不同。我在我的博客上写过,网址: https://cpptalk.wordpress.com/2009/08/23/nuances-of-exception-rethrow/

    非常欢迎你来看看

        6
  •  2
  •   Priyank Bolia    15 年前

    throw ex 将生成另一个副本,不建议使用 throw 只引发当前异常对象。

        7
  •  2
  •   Joshua    15 年前

    throw可以引发catch(…)捕获的非标准异常类型(例如结构化异常)

        8
  •  1
  •   Adam    15 年前

    此外,由于它有时会导致混乱,一个 throw; 在异常处理上下文之外,将中止程序。