2012-04-22 59 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