很少有人知道的c++中的try塊函數


 

 

 

 

 

 

 

c++有一些在現實世界中很少看到的結構。這些結構有着自己的用法,但是要特別小心保守的予以運用。就像是網站 The Old New Thing首頁標題上面的說的那樣:

“代碼通常被讀的次數原因超過了被寫的次數,所以計划要遵循此道。”

在下面將介紹一些很少有人能夠知道的c++構造函數,包括其中的運用場景,語法和陷阱。

運用場景

try函數塊的應用場景一般局限於下面幾個:

(1)構造函數初始化列表;

(2)基類構造含數據;

(3)析構函數;

語法

對於函數

 

void f() try { /*...*/ } catch (...) { /*...*/ }

 

  這等價於

void f() { try { /*...*/ } catch (...) { /*...*/ } }

  對於構造函數初始化列表

struct A : public B
{
    A() try : B(), foo(1), bar(2)
    {
        // constructor body 
    }
    catch (...)
    {
        // exceptions from the initializer list are caught here
        // but also rethrown after this block (unless the program is aborted)
    }

private:
    Foo foo;
    Bar bar;
};

  對於析構函數來說,跟正常函數的使用方法是類似的

struct A
{
    ~A() 
    try
    {
        // destructor body
    }
    catch (...)
    {
        // exceptions from the destructor are caught here
        // but also rethrown after this block (unless the program is aborted)
    }
};

  陷阱

  • 任何在構造函數和析構函數中捕捉的異常,默認情況下都會被重新拋出。這樣的話,大多是情況下當捕捉到一個異常的時候,你能夠做的事情就是用日志記錄,或者是做一些清理工作。不管一個對象因為什么原因而失敗了,你都不應該嘗試去保存它的實例。
  • 在函數catch塊中的return語句表現的跟函數中的返回語句一樣;
  • 但控制流走到catch模塊最后的時候,函數將返回。如果沒有任何返回語句而且函數返回類型是非void的,那么行為將會是不確定的。
  • try塊函數主要有一些非直觀的行為:
    • 從命名空間范圍內定義的構造函數中拋出的異常無法捕捉。
    • 從static變量中獲取的析構函數的對象中拋出的異常無法捕捉。

如上,try模塊函數在進行代碼審查的時候至少是應該引起重視的。try塊函數使用並非都是錯的,在一些上沒有提到的用戶場景中用到的時候,很容易出現問題。

 

 

 

 

 

 

 

 

來源http://szelei.me/rarely-known-cpp-constructs-part-1-function-try-blocks/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM