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 中,我有一个公共方法/函数,它以字符串typenum 的形式接收。但是,当我尝试对其进行测试时,我收到一个询问 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 析构函数已经是virtualpublic。用空的析构函数覆盖它不会改变这一点。顺便说一句:考虑使用std::domain_error 而不是自己编写。

以上是关于C++ 中“覆盖函数的异常规范比基本版本更宽松”的奇怪错误的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中使用 C# 接口或在 C# 中使用 C++ 接口

在 C++ 中制作“对象”| C++ | JS [关闭]

C++ 如何在 C++ 中使用 dlopen()?

十类C++标准库 十类C++标准库简介

在 QML 中创建自定义 C++ 对象并将其存储在 C++ 模型中

动态链接和 Python SWIG (C++) 在 C++ 中工作在 python 中失败