在C ++中通過指針捕獲異常

我發現有三種捕獲異常的方法,有什么區別?

1)抓住價值;

2)通過引用捕獲;

3)被指針抓住;

我只知道按值捕獲將調用該對象的兩個副本,按引用捕獲將調用一個對象。 那么指針捕獲又如何呢? 何時使用指針捕獲? 除了拋出一個對象,我還能拋出一個指向這樣的對象的指針嗎?

class A {}
void f() {
  A *p = new A();
        throw p;
}
asked 2020-02-29T14:51:10Z
5個解決方案
78 votes

推薦的方法是按值拋出并按引用捕獲。

您的示例代碼將拋出一個指針,這是一個壞主意可以领救济金的游戏,因為您將不得不在捕獲站點上管理內存。

如果您真的覺得應該拋出一個指針,請使用諸如shared_ptr之類的智能指針。

無論如何,Herb Sutter和Alexei Alexandrescu在我解釋的C ++編碼標準書中對此做了很好的解釋。

請參閱C ++編碼標準:按值拋出,按引用捕獲。

answered 2020-02-29T14:52:27Z
16 votes

捕獲遵循正常的分配兼容性規則,也就是說可以领救济金的游戏,如果您拋出一個值,則可以將其捕獲為值或引用,但不能將其捕獲為指針。 如果拋出指針,則只能將其作為指針(或對指針的引用...)來捕獲。

但是拋出指針并沒有任何意義,只會導致內存管理的麻煩。 因此,通常應遵循按值引發的規則可以领救济金的游戏,按引用進行捕捉,如Gregory所述。

answered 2020-02-29T14:52:52Z
4 votes

Microsoft的MFC使用按指針捕獲,但是我認為這是為了在正確實現try和catch之前與編譯器兼容。 最初,他們使用TRY和CATCH宏對其進行仿真。 每個異常都源自CException,CException具有確定對象是否需要刪除的方法。

我不建議將其用于任何現代異常設計。 通過引用捕獲是必經之路。

answered 2020-02-29T14:53:18Z
2 votes

盡管實際上可以拋出任何類型的任何對象,但這樣做幾乎沒有什么收獲(如果有的話)。 動態分配主要在對象的生存期不適合自動分配的情況下有用-即您希望其生存期獨立于正常程序范圍。

但是,對于異常對象,這實際上沒有多大意義。 通常,異常對象僅在異常處理程序內部使用,并且您明確希望在退出該異常的(最后一個)處理程序時將其銷毀。

還有一個事實是,您通常希望保持異常處理代碼相當簡單。 僅舉例來說,如果您要報告已耗盡或損壞的空閑存儲/堆,則嘗試從已耗盡/損壞的空閑存儲/堆中分配異常對象通常不會很好地工作...

answered 2020-02-29T14:53:48Z
1 votes

用指針捕獲/拋出異常實際上不是一個好方案。C ++語義允許它,但是它并不是非常有用,因為在大多數情況下,您將拋出一個臨時異常或字符串對象。

但是,某些庫(我相信,Boost.Graph可以做到這一點)使用throw將返回值從深度遞歸的函數傳遞回調用方。 在這種情況下,返回值可能是一個指針,因此拋出一個指針是有意義的。

answered 2020-02-29T14:54:13Z
translate from