我正在解决一个问题,即损坏的输入文件导致抛出异常。异常类是在实现文件中定义的,因此对我来说是不可见的。它确实继承自std::exception
.
我尝试简单地向前声明异常类,因为我只是通过引用捕获它。然而,这给了我一个error: invalid use of incomplete type
编译器错误(在 Linux 上使用 GCC 6.2)。我认为编译器需要完整的异常对象类型,以便它可以在需要时重新抛出异常。
所以这就是我想做的:
// library.cpp
namespace FOO {
struct SomeException : public std::exception
{
// string member, virtual dtor, ctor taking one arg and virtual what()
};
void doStuff() {
}
}
// my main.cpp
namespace FOO
{
struct SomeException;
}
int main()
{
try
{
FOO::doStuff();
}
catch (FOO::SomeException& e)
{
// ignore e, but I know where it came from so log
// an appropriate message
}
catch (std::exception& e)
{
// most other exceptions, log `what()` message
}
catch(...)
{
// tell user to contact customer support
}
}
只需打印what()
消息不适合我的上下文。
我可以要求其他团队将他们的异常类定义移至标头中。这可能会是一个缓慢的过程。我想我也可以对what()
消息,但这看起来很难看。
还有其他选择吗?
(顺便说一句,我在谷歌上看不到任何提及这一点的信息,但这似乎确实是一种反模式,即“仅抛出异常”)。
如果您无权访问原始类,您将无法正确捕获它:
C++ 标准/[except.handle]:
The 异常声明 in a handler描述了以下类型
可能导致该情况的异常handler被输入。
这异常声明不得表示不完整类型、抽象类类型或右值引用类型。
这异常声明不得表示对不完整类型的指针或引用,[ 除外cv void*].
所以没有理想且干净的解决方案。但也许是一个可以接受的解决方法:派生自的类std::异常是多态的。所以你可以考虑使用typeid()(最终结合type_index)来识别真实类型catch (std::exception& e)
堵塞。
恕我直言,这应该是区分未知异常的一种可接受的方法.what()
不是替代方案。然而,不便的是,type_info
数据(例如typeid(e).name()
) 未在标准中定义,这使得任何硬编码值都不可移植。
概念证明:
//somewhere
class MyExcept : public std::exception { };
...
// somewhere else
try {
throw std::exception();
} catch (std::exception &e) {
std::cout <<"case 1: " << typeid(e).name() << std::endl;
}
try {
throw MyExcept();
} catch (std::exception &e) {
std::cout <<"case 2: "<< typeid(e).name() << std::endl;
}
在线演示
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)