15 Exception handling [except]

來源:互聯網
上載者:User

15 Exception handling [except]

1 Exception handling provides a way of transferring control and information from a point in the execution of a program to an exception handler associated with a point previously passed by the execution. A handler will be invoked only by a throw-expression invoked in code executed in the handler’s try block or in functions called from the handler’s try block .

 

 

try-block:

try compound-statement handler-seq

 

function-try-block:

try ctor-initializeropt function-body handler-seq

 

handler-seq:

handler handler-seqopt

 

handler:

catch ( exception-declaration ) compound-statement

 

exception-declaration:

type-specifier-seq declarator

type-specifier-seq abstract-declarator

type-specifier-seq

...

 

throw-expression:

throw assignment-expressionopt

 

A try-block is a statement (clause 6). A throw-expression is of type void. Code that executes a throwexpression is said to “throw an exception;” code that subsequently gets control is called a “handler.” [Note: within this clause “try block” is taken to mean both try-block and function-try-block. ]

 

2 A goto or switch statement shall not be used to transfer control into a try block or into a handler.

[Example:

void f() {

     goto l1; // Ill-formed

     goto l2; // Ill-formed

     try {

         goto l1; // OK

         goto l2; // Ill-formed

l1: ;

     } catch (...) {

l2: ;

         goto l1; // Ill-formed

         goto l2; // OK

     }

}

—end example] A goto, break, return, or continue statement can be used to transfer control out of a try block or handler. When this happens, each variable declared in the try block will be destroyed in the context that directly contains its declaration. [Example:

lab: try {

     T1 t1;

     try {

         T2 t2;

         if (condition)

         {

              goto lab;

         }

     }

     catch(...)

     {

         /* handler 2 */

     }

}

catch(...)

{

     /* handler 1 */

}

Here, executing goto lab; will destroy first t2, then t1, assuming the condition does not declare a variable. Any exception raised while destroying t2 will result in executing handler 2; any exception raised while destroying t1 will result in executing handler 1. ]

 

3 A function-try-block associates a handler-seq with the ctor-initializer, if present, and the function-body. An exception thrown during the execution of the initializer expressions in the ctor-initializer or during the execution of the function-body transfers control to a handler in a function-try-block in the same way as an exception thrown during the execution of a try-block transfers control to other handlers. [Example:

 

int f(int);

class C {

     int i;

     double d;

public:

     C(int, double);

};

C::C(int ii, double id)

try

: i(f(ii)), d(id)

{

     // constructor function body

}

catch (...)

{

     // handles exceptions thrown from the ctor-initializer

     // and from the constructor function body

}—end example]

 

 

 

1.       通過異常處理機制,程式控制流程可以從異常發生點直接跳轉到異常處理模組。通過顯示調用throw語句可以觸發這樣的跳轉。Throw語句必須處於try模組中,或者位於try模組中被調用函數的函數體內。

 

( 此處略去異常處理的相關文法)

 

從整體的角度來看,try模組可以被看作是一個語句(請看下面的相關註解)。throw運算式的傳回型別是void類型。當我們調用throw語句產生一個異常時,我們稱之為”拋出一個異常”。拋出異常後,程式控制流程隨後跳轉所至的模組被稱為”異常處理模組”。[注意:此處的短語”try模組”既指普通的”try模組”,也包括”函數try模組”]

 

2.       我們不應該通過goto或者switch語句強行地將程式控制流程跳轉到 “try模組” 或者 “異常處理模組”中去。

[Example:

void f() {

     goto l1; // 糟糕的風格

     goto l2; // 糟糕的風格

     try {

         goto l1; // OK

         goto l2; // 糟糕的風格

l1: ;

     } catch (...) {

l2: ;

         goto l1; // 糟糕的風格

         goto l2; // OK

     }

}

—end example]
 

      

不過,goto, break, return, 或者 continue 這些語句可以被用來跳出“try模組”或者是“異常處理模組”。一旦程式控制流程跳出了“try模組”或者是“異常處理模組”,那麼在這些模組中聲明的局部變數都將被銷毀(此處並沒有按照英文原文翻譯,請參考英文原文)。

lab: try {

     T1 t1;

     try {

         T2 t2;

         if (condition)

         {

              goto lab;

         }

     }

     catch(...)

     {

         /* handler 2 */

     }

}

catch(...)

{

     /* handler 1 */

}
 

 

在上面的例子中,當我們執行goto lab語句之後, 變數t2首先被銷毀,然後是變數 t1,這裡我們假設 condition沒有聲明額外的變數。如果在銷毀t2的時候發生了異常,程式將會跳轉到 “handler 2” 模組;如果在銷毀t1的時候出了異常,那麼程式控制流程就會跳轉到”handler 1”模組。

 

3. “函數try模組”既可以捕捉到函數體內發生的異常,也可以捕捉到建構函式初始化列表中產生的異常。當建構函式初始化列表或者函數體拋出一個異常時,程式控制流程將會跳轉到相應的”異常處理模組”中去,這和普通的”try模組”的程式控制流程跳轉過程是一樣的。

 

[Example:

 

int f(int);

class C {

     int i;

     double d;

public:

     C(int, double);

};

C::C(int ii, double id)

try

: i(f(ii)), d(id)   // 建構函式的初始化列表

{

     // 建構函式的函數體

}

catch (...)

{

     // 如果 建構函式初始化列表 或者 函數體 拋出了一個異常

     // 程式控制流程將會跳轉到這裡

}—end example]

 
 

 

 

 

相關註解:

l         在C++標準中, try-block 的確被定義為一個statement。下面是相關的定義:

statement:

labeled-statement

expression-statement

compound-statement

selection-statement

iteration-statement

jump-statement

declaration-statement

try-block

 

l         X-seq is one or more X’s without intervening delimiters (e.g. declaration-seq is a sequence of declarations).通過上面的解釋可以看出,handler-seq指的是一個或者多個連續的異常處理模組,中間不摻雜其他的文法單位。下面是多個連續的異常處理模組的例子:

 

catch(int &i )

{

}

catch(char *ch )

{

}

catch(...)

{

}

 
 

 

l         ctor-initializeropt 指的是建構函式初始化列表,下標opt意思是該項為可選項。下面給出的是一個建構函式的函數try模組 的範例。

 

class A

{

public:

     A()

     Try                       ç 請注意try關鍵字所處的位置,其位於右括弧之後,初始化列表的 : 之前

         :

     _k(0)

     {

         // 建構函式,在這個例子中,我們什麼也沒有做

     }

     catch(...)

     {

     }

 

     int _k;

};
 

 

 
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.