2012-03-05 56 views

回答

7

全部捕獲(...)根本不給你訪問異常對象,所以問題是沒有意義的。 [已更正:]throw;反覆投擲原始對象。如果處理程序按值捕獲,則對本地副本的更改不會影響原始的,重新排列的對象。 [/]詳情請參閱15.3(特別是第17章)。

查看右邊的一些相關問題,如this onethis onethis onethis one

+0

如果一個寫'趕上(...){拋出; },那麼它將如何通過價值或借鑑來重新拋出?請注意,在這種情況下,沒有捕捉到原始對象。 – Nawaz 2012-03-05 05:43:22

+0

按價值,還是參考? – Nawaz 2012-03-05 05:45:06

+0

我特別覺得大膽的部分與catch(...)'混淆:*「用throw拋棄;拋出原始對象**,如果最初的異常被引用**捕獲或者在catch-all中被調用,並且「** – Nawaz 2012-03-05 05:46:24

1

拋出的值將拋出的值複製到實現定義的位置。
因此,該值被複制到throw(這意味着該類型必須是可複製的)。

當你發現你可以選擇按價值或參考捕獲。

catch(X val) // Catch by value 
{ 
} 
catch(Y& val) // Catch by reference 
{ 
} 

習慣性的爲什麼要趕上const引用。這是因爲,如果按值捕獲,當異常從其保存的位置複製到捕獲值時,可能會發生切片。如果按值捕獲,則該值在catch塊的末尾被銷燬。保存位置的副本在try/catch塊的末尾被銷燬(並且不會被重新拋出)。

所以,當你碰到catch(...)什麼都沒有發生。異常保留在異常已被複制到的未指定位置。

當你使用throw來重新拋出異常。 throw;。由於異常已經在未指定的位置並且什麼都不需要發生,因此再次沒有任何反應。

注意:在沒有異常傳播時調用throw;是錯誤,並且會導致調用std :: terminate。

+0

關於問題提出的「catch(...){throw;}」怎麼樣? – 2012-03-05 06:43:05

+0

@MooingDuck:對不起,我只是想首先解釋主要部分的上下文。 – 2012-03-05 06:53:01

2

你總是抓住你拋出的東西。 假設你有一個異常類

class MyException { 
public: 
    int m_data; 
    MyException(int data) 
    { 
     printf("MyException::MyException() ctor\n"); 
     m_data = data; 
    } 

    MyException(const MyException & other) { 
     printf("MyException::MyException() copy ctor\n"); 
    } 

    ~MyException() 
    { 
     printf("MyException::~MyException() dtor\n"); 
    } 
}; 

1)如果你拋出一個指針,你會得到指針:

例1:

void f() 
{ 
    throw new MyException() 
} 

void main() 
{ 
    try{ 
     f(); 
    }  
    catch(MyException * ex) // You WILL catch the pointer 
    { 
     delete ex; // You should delete the exception object 
    } 
    catch(MyException & ex) // You WILL NOT catch the pointer 
    { 
    } 
} 

例2:

void main() 
{ 
    try{ 
     f(); 
    } 
    catch(...) // You WILL catch the pointer, but will be unable to access it 
    { 
     throw; // You are rethrowing the pointer 
    } 
} 

2)如果已拋出的對象時,你會趕上對它的引用:

實施例1:

void f() 
{ 
    printf("f BEGIN\n"); 
    throw MyException(1); // MyException ctor is called 
    printf("f END\n"); 
} 

void main() 
{ 
    printf("main BEGIN\n"); 

    try 
    { 
     f(); 
    } 
    catch(MyException & ex) // You WILL catch a reference to created object 
    { 
     printf("catch MyException: %d\n", ex.m_data); 
    } // MyException dtor is called here!! 

    printf("main END\n"); 
} 

以下輸出產生:

main BEGIN 
f BEGIN 
MyException::MyException() ctor 
catch MyException: 1 
MyException::~MyException() dtor 
main END 

實施例2:

void main() 
{ 
    try 
    { 
     f(); 
    } 
    catch(...) // You WILL catch a reference to created object, 
       //but will be unable to access it 
    { 
     throw; // You throw the reference 
    } 
}