我想自定义一个Exception类,这是代码:
class TestException : std::exception{
public:
const char *what() const override {
return "TestException";
}
};
我曾经使用过Clion,IDE则对功能what()
:exception specification of overriding function is more lax than base version
但是,如果我使用gcc构建代码,则不会发出警告。 我用的是c ++ 14,gcc 6.5.0
有人可以帮助解释警告的含义吗,我可以忽略它吗?
答案 0 :(得分:6)
what
的 std::exception
成员函数被声明为noexcept
。因此,您还应该使被覆盖的what
noexcept
也是如此。 (实际上,这就是错误消息的内容。)
请注意,noexcept
关键字必须位于override
关键字之前(有关详细信息,请参见The order of override and noexcept in the standard)。
答案 1 :(得分:5)
std::exception
中的 what
是virtual
函数,并且派生类中的virtual
函数不能具有比函数宽松的 exception规范它在基类中重写。
在标准的“异常说明”部分中提到了这一点。
18.4异常规范[spec.except除外]
...
4.如果虚函数具有非抛出异常规范,则在任何派生类中覆盖该虚函数的任何函数的所有声明(包括定义)都应具有非抛出异常规范,除非将超越函数定义为已删除。
给出的示例(与问题中的代码有些相似)也对此进行了说明。
struct B
{
virtual void f() noexcept;
virtual void g();
virtual void h() noexcept = delete;
};
struct D: B
{
void f(); // ill-formed
void g() noexcept; // OK
void h() = delete; // OK
};
D::f
的声明格式错误,因为它具有可能抛出的异常说明,而B::f
有一个非抛出的异常说明。
解决方案是更改代码,例如:
class TestException : std::exception{
public:
const char *what() const noexcept override {
return "TestException";
}
};
在此处查看compilation。
答案 2 :(得分:1)
您面临的警告与您正在使用C ++ 14的事实有关,如果您将使用C ++ 17进行编译,则这将成为错误。因此,我不建议您忽略它。
怎么回事?
std::exception
将方法what
定义为:virtual const char* what() const noexcept;
。您从该方法继承,然后在不指定noexcept
的情况下重新实现它。结果是,您告诉您的实现可以抛出异常,而基本方法指示此异常不应抛出。 (呼叫者会这样假设)
此问题已在C ++ 17中修复,这使noexcept
成为类型系统的一部分,并要求您修复以下代码:
const char *what() const noexcept override