首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >方法/构造函数签名中包含和不带抛出()的自定义异常的c++

问方法/构造函数签名中包含和不带抛出()的自定义异常的c++
EN

Stack Overflow用户
提问于 2017-09-02 07:27:33
回答 2查看 1.1K关注 0票数 8

我是c++的初学者,因此对这个愚蠢的问题表示歉意。我在这里张贴它,因为我找不到类似的答案堆叠溢出。

我正在通过C++中的异常进行处理,当我处理一些自定义异常时,我有以下代码

代码语言:javascript
复制
class MyException: public std::exception{
public:
    virtual const char* what() const throw() {
        return "something bad happened";
    }

};

// class that throws above exception

class canGoWrong {
public:
    canGoWrong(){
        throw MyException();
    }
};

以上代码是由老师展示的。构造函数刚刚实现了基类exception中定义的虚拟函数。我要到那为止。

现在,当我尝试一个不同的版本来练习时,我尝试使用一个自定义函数,而不是重新定义虚拟(因为c++没有严格执行接口的概念,如果我错了,请纠正我)。

我把它写成

代码语言:javascript
复制
class my_custom_shit_exception: public std::exception {
public:
    const char* show() { // I omitted the const throw() here
            return "This is an error encountered\n";
    }
};

class myclass {
public:
    myclass() {
        throw my_custom_shit_exception();
    }
};

总之,我没有发现两种方式在行为上都有区别

代码语言:javascript
复制
public:
const char* show() {
        return "This is an error encountered\n";
}
virtual const char* what() const throw() {
    return "something bad happened";
}
  • 那么,为什么在const throw()虚拟函数中使用what()呢?这有什么区别?

多亏了所有人。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-02 07:55:54

函数签名

代码语言:javascript
复制
class std::exception {
    //...
public:
    virtual const char* what() const throw();
    //...
};

可以读为:what是std::exception的虚拟成员函数,它返回指向常量字符(数组)的指针,并且不修改该对象的成员(因此是第二个const),并保证不会在其代码中抛出异常。

请注意,现在不推荐使用异常规范:相反,由于C++11有noexcept说明符来声明“保证”不抛出异常的函数。此外,自C++17以来,throw()已成为noexcept(true)的同义词,但其行为略有不同。

有关详细信息,请参阅这一描述 of noexcept。

它还说:“注意,函数的no以外规范不是编译时检查;它只是程序员通知编译器函数是否应该抛出异常的一种方法。编译器可以使用这些信息对非抛出函数进行某些优化……”。

票数 4
EN

Stack Overflow用户

发布于 2017-09-02 08:22:36

我想展示一些斯科特·迈耶斯的名言

“有效C++”第三版

int doSomething() throw(); // note empty exception spec. 这并不是说doSomething永远不会抛出异常,而是说如果doSomething抛出异常,这是一个严重的错误,应该调用意外的函数。† 有关意外功能的信息,请查阅您最喜欢的搜索引擎或全面的C++文本。(您可能会更幸运地搜索指定意外函数的set_unexpected函数。)

从“有效的现代C++”

在C++11中,无条件的no以外是用于保证它们不会发出异常的函数。 如果在运行时,异常离开f,则违反f的异常规范。有了C++98异常规范,调用堆栈就会向f的调用方解除,并且,在这里的一些操作不相关之后,程序执行就会终止。对于C++11异常规范,运行时行为略有不同:只有在程序执行终止之前,堆栈才可能解除。展开调用堆栈与可能展开调用堆栈之间的区别对代码生成有着惊人的巨大影响。在no境外函数中,如果异常将从函数中传播出去,优化器不需要将运行时堆栈保持在不可缠绕的状态,也不需要确保在异常离开函数时,no境外函数中的对象按反构造顺序被销毁。带有“抛出()”异常规范的函数缺乏这种优化灵活性,没有异常规范的函数也是如此。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46011519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档