2017-03-17 79 views
0
template <typename T> 
Blob<T>::Blob(std::initializer_list<T> il) try : 
data(std::make_shared<std::vector<T>>(il)) { 
/* empty body */ 
} catch(const std::bad_alloc &e) { handle_out_of_memory(e); } 

C++入門第五版779頁說爲什麼初始化列表構造函數參數時,異常發生?

Notice that the keyword try appears before the colon that begins the constructor initializer list and before the curly brace that forms the (in this case empty) constructor function body. The catch associated with this try can be used to handle exceptions thrown either from within the member initialization list or from within the constructor body. It is worth noting that an exception can happen while initializing the constructor’s parameters. Such exceptions are not part of the function try block. The function try block handles only exceptions that occur once the constructor begins executing. As with any other function call, if an exception occurs during parameter initialization, that exception is part of the calling expression and is handled in the caller’s context.

我很困惑,不能想到的,當它發生在那裏/的情況下,任何人都可以給我 一個例子嗎?

+3

從這種情況出發,很難通過「初始化構造函數的參數」知道它們的含義。必須評估* any函數調用的參數,這可能導致異常,尤其是如果這些參數是從函數調用派生的。 –

+0

@MarkRansom我已經添加了更多信息,現在我想你可以知道他們的意思了。 –

+1

你應該改變標題,看起來你是通過成員初始化列表來詢問成員的初始化,而不是關於參數初始化。班級成員不是參數 –

回答

2

下面是一個例子:

struct S 
{ 
    S(char *); 
}; 

int main() 
{ 
    S s(new char[0x7FFFFFFF]); 
} 

new char[0x7FFFFFFF]可能會引發內存外的一個例外。

+0

此代碼無法編譯:錯誤C2148:數組的總大小不得超過VS2015中的0x7fffffff字節,在VS2010中也一樣。 – HDJEMAI

+0

錯誤:「新」中的數組大小在VS2010中也必須是非負數。 – HDJEMAI

+0

@ H.DJEMAI編輯我的回答 –

0

如果初始化參數時內存不足。

-1

例如:拋出異常:讀取訪問衝突。

#include <iostream> 

using namespace std; 

class X 
{ 
    int a; 
    int b; 
    int* c; 

    public: 
     X(int a, int b, int* c = nullptr) try : a(a), b(b=c[0]) 
     { 
     } 
     catch (...) 
     { 
      cout << "Exception occured"; 
     } 
}; 

int main() 
{ 
    X v(1,0); 

    return 0; 
} 

Message: c was nullptr.

+1

除以零是未定義的行爲;這當然不是這本書的意思。在這種情況下,它是Microsoft編譯器的非標準擴展,用於生成未處理的異常 –

+2

您的異常發生在初始化列表中,它在初始化構造函數的參數時不會發生。函數try塊可以處理這個。 –

+0

未處理的異常,其中由VS2015和VS2010顯示 – HDJEMAI

-1

當一個例外是投一個構造函數調用可能會發生這樣的事;隱式或顯式。

例如:

class spam { 
public: 
    spam(int eggs) { 
     throw std::exception(); 
    } 
}; 

class foo { 
public: 
    spam unused; 
    const int q; 
    foo() try : unused(1), q(123) { 

    } catch(std::exception& e) { std::cout << "spamspamspam\n";} 
}; 

int main() { 
    try { 
     foo f; // exception thrown 
    } catch (std::exception& e) { 
     std::cout << "It didn't stop there!\n"; 
    } 
    return 0; 
} 

打印在終端上 「!spamspamspam \ n它並沒有就此停止\ n」,然後退出與中止。請注意,該異常可以被捕獲,但之後會繼續傳播。這是因爲在投擲者之後初始化的任何成員實際上都是而不是已初始化,並且const成員或引用(如const int q在我的示例中)在語法上不可能在稍後的時間點進行初始化。所以答案是完全中止構造函數調用。

+0

thx,你可以理解爲什麼會發生第二個異常。初始化構造函數的參數時,第一個和第二個異常都不會發生,儘管一個函數try塊不能解決問題。這有很大的幫助,我希望你不會刪除答案。 –

相關問題