我是 C++ 的新手,但我想在向 Microsoft 报告错误之前确保我没有做错任何事情。
下面是一些示例代码:
#include <system_error>
using namespace std;
class Test
{
public:
~Test()
{
throw system_error(5, system_category());
}
};
Test test;
void testfunc()
{
throw system_error(5, system_category());
}
void main()
{
try
{
testfunc();
}
catch ( const system_error& e)
{
}
}
现在,我希望 Windows 会说“运行时已请求程序以意外方式退出”。但是,我得到的是“称为纯虚函数”的错误。通过一些调试,我注意到当静态类析构函数获取 std::system_category
引用时,::name
和 ::message
成员(member)是纯虚拟的。但是,当它在 testfunc()
中构造时,那些 vtable 指针指向有效函数。
我的问题是,以这种方式构造我的 system_error
异常是不是做错了什么?我有一些代码基本上是在做 throw system_error(GetLastError(), system_category());
。这恰好在一个静态析构函数中执行,我得到了一个名为 error 的纯虚函数。
要从 Windows 的 GetLastError()
函数中抛出异常,我应该以不同的方式构造我的异常,还是这是 msvc11 的 C++ 运行时中的错误?
编辑
我的问题有些困惑。我的实际代码比这个例子更复杂,我实际上没想到我的一个析构函数会抛出异常。我的析构函数必须调用一个可能会抛出异常的函数。如果我将代码更改为:
~Test()
{
try
{
callSomeFuncThatCouldThrow();
}
catch ( … ) { }
}
我仍然得到纯虚函数调用错误。这是因为在构造 system_error 时(在 callSOmeFuncThatCouldThrow()
中)它尝试使用 system_category
的 ::message
成员给它,这会导致错误。
最佳答案
看起来像 Microsoft 的错误。 std::error_category
是各种未命名类型的抽象基类,其中之一就是system_category()
返回的类型。有一个该类型的对象,所有对 system_category()
的调用都会返回对该对象的引用。您所看到的看起来像是该对象在 test
对象的析构函数运行之前被销毁了。如果您想满足纯粹主义者,请将析构函数更改为:
Test::~Test() {
const std::error_category& cat = std::system_category();
std::cout << cat.name() << '\n';
}
关于c++ - 在带有 msvc11 的静态类析构函数中使用 std::system_category(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12646165/