2014-09-01 82 views
1

從這樣的函數拋出異常是非法的嗎?
在Eclipse中它工作...
所以這是真的嗎?我們可以拋出內部對象來拋出異常?從函數中拋出內部對象異常是合法的

class Bad { 
    int i; 
public: 
    void what() { cout << "exp" << i; } 
}; 

class A { 
public: 
    void f() { 
     Bad e; 
     throw e; 
    } // e are deleted by d'tor? 
}; 

int main() { 
    A a; 
    try { 
     a.f(); 
    } catch (Bad& e) // What happen here? we catch reference to some object that 
        // was deleted by Bad dt'or 
    { 
     cout << "in catch"; 
     e.what(); // what happen here? 
    } 
    return 0; 
} 
+1

很明顯,不是重複的,@ bames53。 – 2014-09-01 19:23:17

+0

與'return e;'作用相同,而不是返回本地創建副本。 – Vladp 2014-09-01 19:25:56

+0

@LightnessRacesinOrbit對我來說這似乎很清楚,它是重複的。 http://stackoverflow.com/questions/1860064/catching-exception-objects-by-reference-temporaries-lifetime-issues這兩個問題都在問,如何通過引用來捕獲在範圍退出時被銷燬的對象是可能的,因爲在這一點上不應該引用無效? – bames53 2014-09-02 16:38:34

回答

3

你的代碼沒問題。 throw e;作出e的副本,這是在已被處理後破壞。處理程序被給予對該副本的引用。

如果你拋出一個指向局部變量的指針,你可能會遇到麻煩;變量在處理異常之前會被銷燬,導致指針無效。但是在任何情況下拋出一個指針都是一件很奇怪的事情。

+0

所以,爲什麼扔e ==拋出壞(e).. 我覺得這很奇怪.. – 2014-09-01 18:36:23

+0

@ItayAveksis:因爲拋出一個對象被指定爲複製對象,因爲這避免了你在問題:在處理異常之前,對象本身在堆棧展開期間被銷燬。這與'throw Bad(e)'不同,它會使*兩個副本:臨時的'Bad(e)'和所引發的副本。 – 2014-09-01 18:41:06

+0

謝謝。 現在它的理解 – 2014-09-01 18:43:59