C++ 如何从私有成员子类对象捕获异常?
给定下面的伪代码,我想捕获类B中的子对象a引发的异常,在B中维护此对象的私有性。下面所述的catch子句不起作用,因为对象a在B中是私有的。我如何捕获此异常 编辑我更改了伪代码,将类A嵌入到类B中C++ 如何从私有成员子类对象捕获异常?,c++,C++,给定下面的伪代码,我想捕获类B中的子对象a引发的异常,在B中维护此对象的私有性。下面所述的catch子句不起作用,因为对象a在B中是私有的。我如何捕获此异常 编辑我更改了伪代码,将类A嵌入到类B中 class B { class A { public: class Exception{}; A() throw(Exception) { ... } // A ctor throws an Exception class object
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& )
{
...
}
}
您不需要在
catch
子句中说B::A::Exception
,除非类A
是在B
中定义的。现在您已经对其进行了编辑,如果A
在B
之外可见,B::A::Exception
在A
之外可见,或者如果B::A::Exception
以其他方式(如通过typedef,)可用,B::A::Exception
是合适的
如果不是,你就不应该扔了。(在这种情况下,不是这样的,所以是的。不要这样做。)如果人们甚至看不到异常的类型,他们怎么能合理地捕捉到这种异常
实现这一点的一种方法是将类的声明与成员变量的声明分开。有点像
class B {
public:
B() { }
class A {
public:
class Exception {};
A() { /* throw Exception(); */ }
};
private:
A a;
};
但是坦率地说,typedef听起来更优雅。你不需要在
catch
子句中说B::A::Exception
,除非类A
是在B
中定义的。现在您已经对其进行了编辑,如果A
在B
之外可见,B::A::Exception
在A
之外可见,或者如果B::A::Exception
以其他方式(如通过typedef,)可用,B::A::Exception
是合适的
如果不是,你就不应该扔了。(在这种情况下,不是这样的,所以是的。不要这样做。)如果人们甚至看不到异常的类型,他们怎么能合理地捕捉到这种异常
实现这一点的一种方法是将类的声明与成员变量的声明分开。有点像
class B {
public:
B() { }
class A {
public:
class Exception {};
A() { /* throw Exception(); */ }
};
private:
A a;
};
但是坦率地说,typedef听起来更优雅。在周围类的异常中添加一个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& )
{
}
}
向周围类中的异常添加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& )
{
}
}
由于
A
是私有的,因此无法访问类型Exception
来捕获它。有几种解决方案,首先是抓住任何东西:
try {
B b;
} catch(...) {
}
第二种方法是创建一个在main中可见的分离异常类
最后,您可以使您的
B::A::Exception
扩展std::Exception
并捕获std::Exception
,因为A
是私有的,所以您无法访问类型Exception
来捕获它。有几种解决方案,首先是抓住任何东西:
try {
B b;
} catch(...) {
}
第二种方法是创建一个在main中可见的分离异常类
最后,您可以使您的
B::A::Exception
扩展std::Exception
并捕获std::Exception
,您可能需要重新考虑在构造函数中抛出异常。(抛出异常时不会调用析构函数)
例外情况确实适用于例外情况。不要过度使用它们 您可能需要重新考虑在构造函数中抛出异常。(抛出异常时不会调用析构函数)
例外情况确实适用于例外情况。不要过度使用它们 如果这个异常是要在其他类中捕获的,那么它就不应该是私有的谢谢你完全改变了这个问题的含义…:如果这个异常是在其他类中捕获的,那么它就不应该是私有的谢谢你完全改变了这个问题的含义…:你们可以看到,我刚刚编辑了我的问题,将A类嵌入到B类中。谢谢。是的,别问了它改变了问题的意义,使任何已经给出的答案无效。如果您的问题发生了很大的变化,通常最好问一个新问题。问题是,虽然a在B中可见,但对象a在B中是私有的,因此表达式B::a::Exception&在main()中无效。正如您所看到的,我刚刚编辑了我的问题,将类a嵌入B中。谢谢。是的,请停止该操作:它改变了问题的意义,使任何已经给出的答案无效。如果您的问题发生了如此大的变化,通常最好问一个新问题。问题是,虽然a在B中可见,但对象a在B中是私有的,因此表达式B::a::Exception&在main()中无效。正如您所看到的,我刚刚编辑了我的问题,将类a嵌入B中。谢谢。@user1162978有效地简化了这一过程。只需使用
typedef
。请不要在代码示例中使用省略号。这使得copy-paste-compile
对于试图回答问题的人来说难度更大。这太棒了。谢谢!正如您所见,我刚刚编辑了我的问题,将类A嵌入到B中。谢谢。@user1162978有效地简化了这一过程。只需使用typedef
。请不要在代码示例中使用省略号。这使得copy-paste-compile
对于试图回答问题的人来说难度更大。这太棒了。谢谢!析构函数将被称为罚款,除非你的C++编译器被破坏,或者你指望破坏一个你从未实际构造的对象。直到构造函数结束,对象才完全成形,因此这种语义是合理的。@6502:我就是这么说的……如果你从来没有构造过对象,为什么要将其销毁?@cHao:carleeto说的是,在构造函数中抛出异常包含了一些微妙之处,可能会很危险。不在部分构造的对象上调用析构函数的想法是合理的,但仍然令人惊讶(因为您必须手动撤消部分构造,可能会重复代码)。如果