2012-04-22 57 views
1

給定下面的僞代碼,我想要捕獲B類中的子對象a引發的異常,並將此對象保留在B中。下面所述的catch子句不起作用,因爲對象a是私有的B.我怎樣才能捕捉到這個異常?如何從私有成員子類對象中捕獲異常?

編輯我已經改變了僞代碼嵌入類B.內A類

class B 
{ 
    class A 
    { 
     public: 
     class Exception{}; 
     A() throw(Exception) { ... } // A ctor throws an Exception class object 
    } a; 
    public: 
    B() { ... }  // B ctor 
}; 

int main() 
{ 
    try 
    { 
     B b; 
    } 
    catch(B::A::Exception&) 
    { 
     ... 
    } 

} 
+2

如果異常是指在其他類別被抓住,那麼它不應該是私人 – 2012-04-22 21:38:35

+0

感謝徹底改變這個問題的意思...:P – cHao 2012-04-22 21:47:11

回答

1

向周圍類中的異常添加typedef。

class B 
{ 
    class A 
    { 
     public: 
     class Exception{}; 
     A() throw(Exception) { } // A ctor throws an Exception class object 
    } a; 

public: 
    typedef A::Exception Except; 
    B() { }  // B ctor 
}; 

int main() 
{ 
    try 
    { 
     B b; 
    } 
    catch(B::Except&) 
    { 

    } 

} 
+0

正如你所看到的,我剛剛編輯了我的問題,在B中嵌入了A類。謝謝。 – WaldB 2012-04-22 21:48:09

+0

@ user1162978有效地使這更容易。只需使用'typedef'。請勿在代碼示例中使用省略號。這使得試圖回答的人更難以複製粘貼編譯。 – pmr 2012-04-22 21:57:25

+0

太棒了。非常感謝 ! – WaldB 2012-04-22 22:11:48

3

你不需要說B::A::Exceptioncatch子句中,除非類A在裏面B定義。現在,您已經將其編輯成使這樣也好,B::A::Exception爲宜如果ABException可見外面的A外可見...或者,如果B::A::Exception取得提供一些其他方式(如通過一個typedef,as suggested by pmr)。

如果不是,你不應該拋棄它。 (在這種情況下,不是這樣,不要那樣做。)如果有人能夠合理地捕捉到這種異常情況,如果他們甚至看不到它的類型?

您可以使這項工作的一種方式是從成員變量的聲明中拆分類的聲明。有點像

class B { 
public: 
    B() { } 

    class A { 
    public: 
     class Exception {}; 
     A() { /* throw Exception(); */ } 
    }; 
private: 
    A a; 
}; 

但坦白地說,typedef的聲音的方式更優雅。

+0

正如你可以看到我剛剛編輯我的問題在B內嵌入A類。謝謝。 – WaldB 2012-04-22 21:47:41

+0

是的,停下來。 :P它將問題的含義改變爲使已經給出的任何答案無效的點。如果你的問題發生了很大的變化,最好問一個新問題。 – cHao 2012-04-22 21:51:24

+0

問題是雖然A在B中可見,但對象a在B中是私有的,所以表達式B :: A :: Exception&在main()中無效。 – WaldB 2012-04-22 21:54:46

0

由於A是私有的,你不能訪問類型Exception抓住它。有幾個解決方案,首先是趕什麼:

try { 
    B b; 
} catch(...) { 
} 

二是建立一個分離的異常類,在主要是可見的。

最後,你可以讓你的B::A::Exception延長std::Exception,趕上std::Exception

1

您可能想重新考慮在構造函數中拋出異常。 Here's why(拋出異常時不會調用析構函數)

異常事實上是出於特殊情況。不要過度使用它們。

+0

除非你的C++編譯器被破壞,否則析構函數會被調用,或者你正在破壞一個你從未實際構建過的對象。 – cHao 2012-04-22 22:22:40

+1

@cHao:如果在構造函數中拋出異常,則不調用類的析構函數。該對象直到構造函數結束才完全形成,因此該語義是合理的。 – 6502 2012-04-22 22:29:13

+0

@ 6502:這就是我所說的......如果你從未設法構造這個物體,爲什麼它會被破壞? – cHao 2012-04-22 22:45:28