C++ 中“覆盖函数的异常规范比基本版本更宽松”的奇怪错误
Posted
技术标签:
【中文标题】C++ 中“覆盖函数的异常规范比基本版本更宽松”的奇怪错误【英文标题】:Weird error on 'exception specification of overriding function is more lax than base version' in C++ 【发布时间】:2020-01-26 14:39:55 【问题描述】:做一个项目,我试图用一堆类创建一个 HandleError 标头。在我的班级BadNumber
中,我有一个公共方法/函数,它以字符串type
和num
的形式接收。但是,当我尝试对其进行测试时,我收到一个询问 exception specification of overriding function is more lax than base version
的错误,因为我是从 public std::exception
继承它的。我用谷歌搜索了如何解决这个问题,它建议我在我的what()
中为这个异常调用(link here)做一个 noexcept 覆盖调用。该示例与我的示例几乎相同,但错误消息相同。
代码(使用GCC/Clang c++11编译):
#include <exception>
#include <string>
class BadNumber : public std::exception
private:
std::string _msg;
public:
BadNumber(std::string type, std::string num) : _msg(num + "is invalid type for " + type)
const char *what() const noexcept override
return (_msg.c_str());
;
错误信息:
src/../inc/HandleError.hpp:23:15: error: exception specification of overriding function is more lax than base version
const char *what() const noexcept override
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/exception:102:25: note: overridden virtual function is here
virtual const char* what() const _NOEXCEPT;
我按照要求做了并做了一些研究,但仍然没有运气,而且还在做更多的事情。非常感谢您的帮助,尽可能获得一些反馈和建设性总是有帮助的。感谢您的时间和耐心:)
【问题讨论】:
您能告诉我们_NOEXCEPT
宏的计算结果吗?另外,你用的是什么编译器?
当然,它是用c++11
编译的,_NOEXCEPT
是:/Library/Developer/CommandLineTools/usr/include/c++/v1/exception:102:25: note: overridden virtual function is here virtual const char* what() const _NOEXCEPT;
我也会把它添加到原帖中,这样更清楚
不是我的意思! c++11 是标准 - 你使用什么工具(GCC?)。而且我没有你指出的头文件,所以请查找_NOEXCEPT
的定义并告诉我们它是什么。
如果在覆盖中将noexcept
替换为_NOEXCEPT
会怎样?如果编译成功,您需要深入了解该宏的定义。为此,将#define
放在顶部(在你之前#include
任何东西)到某个随机值。然后,您将在原始定义的位置收到警告/错误。
好的,我们已经成功了一半!在我的系统(MSVC 和/或 Clang)上,exception
标头中没有使用或定义 _NOEXCEPT
,这就是为什么我想知道 它在您的系统上的定义 .尝试右键单击它并选择“查找定义”或类似内容。
【参考方案1】:
所以我意识到我必须将每个类都作为虚拟析构函数,否则我会使用我不想这样做的基本析构函数。这是我的解决方案:
class BadNumber : public std::exception
private:
std::string _msg;
public:
virtual ~BadNumber() throw() return ;
BadNumber(std::string type, std::string num) : _msg(num + "is invalid type for " + type)
virtual const char *what() const throw()
return (_msg.c_str());
;
【讨论】:
这没有意义:std::exception
析构函数已经是virtual
和public
。用空的析构函数覆盖它不会改变这一点。顺便说一句:考虑使用std::domain_error
而不是自己编写。以上是关于C++ 中“覆盖函数的异常规范比基本版本更宽松”的奇怪错误的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中使用 C# 接口或在 C# 中使用 C++ 接口