【问题标题】:What is the purpose of using throw after function signature in c++?在 C++ 中使用函数签名后抛出的目的是什么?
【发布时间】:2014-01-27 13:03:21
【问题描述】:

据我了解,c++ 中的异常将使用 throw 语句显式调用

 void exp()
 {
    try{    
       int a,b=0;
       if(b==0)
       {
          throw b; // called explicity
       }
       a=10/b;
    }
    catch(...)
    {

       //   cout<<"Exception called\n"<<e;
    }    
 }

给定以下 sn-p:

void myfunction(.............)throw(SQLEXCEPTION)
{
    //my stuff
}
  1. 在函数签名之后使用 throw 的目的是什么。
  2. 可以为此类 throw 定义 catch 块。
  3. 是否会隐式处理异常。
  4. 如果不隐式处理,在什么情况下会执行 throw。

【问题讨论】:

    标签: c++ exception


    【解决方案1】:

    函数签名中的throw() 指定函数可能抛出的异常。

    例子:

    void foo() throw(std::runtime_error, std::logic_error);
    

    throw() 不带参数表示函数不抛出异常

    异常规范已弃用,不推荐使用。

    【讨论】:

      【解决方案2】:

      1- 在函数签名后使用throw(type-list) 是为了让您或将阅读您的代码的程序员知道该函数只能抛出您在@987654323 中指定的类型@。

      void f()throw(){};// This function can not throw any object of any type.
      void f()throw(A){}; // you can throw any A object + 
                         // any object of a type drived from A if A is a User-defined Type
      

      如果你抛出一个不在异常规范中的类型的对象,std::unexpected() 函数将被调用。

      2-这里没有catch块。函数签名后的throw(type-list) 只是为了确保该函数不会抛出除type-list 中类型的对象之外的任何类型。

      您使用的称为异常规范,它的一个使用示例如下:

          int f(int x)throw(int){
                   if (x==0) throw 0;
                    return x;
          }
      
          int main(){
          try{
              f(0);  
             }
          catch(int e){
           // something
             }
          }
      

      你可以记住两件事:

      i) 不要使用异常规范,因为它们已被弃用。
      ii) 如果您必须使用它们,那么您现在必须使用某些编译器拒绝内联一个函数,因为它有一个异常规范。


      更新:

      void f()throw(int){
            try{
             // code goes here ...
             throw 1.1; // note this is throwing a float
            }
            catch(float){
            // exception handled
            }
      
        }
      

      在这个例子中你不会得到任何错误,即使你抛出一个float类型的异常,这在函数异常规范中没有指定,它只允许你抛出int类型的对象。这是因为您在函数内部处理了异常。


      void f()throw(int){
              throw 1;
      
       }
       int main(){
             try{
                 f();
      
             }
             catch(int){// exception handled}
      
       }
      

      您应该始终将您认为可能会引发异常的函数放在try-block 中,因为f() 引发int 并得到处理,所以上面的代码将被正常执行。


      void f()throw(int){
      
         throw 1.1; // note this is throwing a float
      
       }
      
       int main(){
          try{ 
             f();
      
          }
        catch(...){//}
       }
      

      这将导致函数调用std::unexpected(),因为您的函数f() 抛出了一个不在函数异常规范中的float 类型的异常。

      【讨论】:

      • 根据您的声明“除了类型列表中的类型对象外,不会抛出任何类型”但是请注意这里抛出 char* 怎么可能......它被 catch 块 ideone.com/h2msQ5 捕获
      • @Vinoth 在你的情况下,你在你的函数中抛出的对象总是在你的函数中处理,这意味着 exp() 不会抛出任何异常。我们说一个函数在函数体内部没有处理时会抛出异常。
      • "函数在函数体内没有处理时抛出异常" 这句话的意思是“如果我们的函数没有处理任何异常,它会抛出它,程序不会崩溃”。是正确的。例如,如果除以零放在函数内部,如果函数签名后抛出逻辑错误异常。程序不会崩溃...
      【解决方案3】:

      函数声明上的throw() 规范指示允许该函数向调用者抛出哪些特定异常。这是一种契约,所以调用者知道会发生什么。如果没有指定throw(),则允许该函数抛出任何异常。如果throw() 为空,则不允许该函数抛出任何异常。因此,在您的示例中,myfunction() 只允许抛出 SQLEXCEPTION 和派生异常。

      【讨论】:

        【解决方案4】:

        throw 的目的是程序员在创建异常。

        例如,您可以有一个自定义数组对象来检查它是否在边界内,如果不在则抛出异常。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-03
          • 2022-06-28
          • 2018-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-16
          • 2010-11-06
          相关资源
          最近更新 更多