【问题标题】:How I need to work with the virtual function "what()"?我需要如何使用虚函数“what()”?
【发布时间】:2018-03-15 19:27:13
【问题描述】:

给定一个类Stack(例如):

class Stack {
    // ...
    class Exception : public std::exception {};
    class Full : public Exception {};
    class Empty : public Exception {};
};

让我们看看下一个函数f(例如):

void f() {
    try {
        Stack s(100); // Only for the example. 
    } catch (Stack::Full& e) {
        cerr << "Not enough room";
    } catch (Stack::Exception& e) {
        cerr << "Error with stack";
    } catch (std::exception& e) {
        cerr << e.what() << endl;
    }
}

如果它转到最后一个catch,输出会是什么?
我需要在 Exception 类中声明 what() 函数才能正常工作?

【问题讨论】:

  • 你应该扔东西,否则什么都抓不到。
  • @liliscent:你怎么知道Stack s(100);不扔?
  • @VittorioRomeo 基于发布的代码。
  • @VittorioRomeo 我不是,但我的问题是关于what() 函数,e.what() 的输出是什么?
  • what 是std::exception 类的虚拟方法,您可以在异常类中重写它以提供您想要的任何文本。这就是派生自 std::exception 的异常类通常会做的事情。

标签: c++ exception polymorphism virtual-functions


【解决方案1】:

std::exception 的虚拟 what() 方法是向异常提供有意义消息的好方法,也是始终基于 std::exception 创建自己的异常的好理由。

这种方法的好处是它是 STL 的标准化部分。 STL 异常在what() 中返回有意义的消息。 这也意味着,如果您要在 Stack 中的某处使用套接字代码,您将使用 catch (std::exception&amp; e) 捕获它,并且可以例如在不了解有关异常的更详细信息的情况下打印出错误消息。

与此相反,非标准化方法显然只有在显式捕获特定已知类型的异常时才可用。

就您的示例而言,这意味着您可以像这样创建异常:

class Stack {
    // ...
    class Exception : public std::exception {
        virtual const char* what() override { return "Unspecified stack error"; }
    };
    class Full : public Exception {
        virtual const char* what() override { return "Stack is full"; }
    };
    class Empty : public Exception {
        virtual const char* what() override { return "Stack is empty"; }
    };
};

然后你在你的 try/catch 中只需要 catch std::exception:

void f() {
    try {
        Stack s(100); // Only for the example. 
    } catch (std::exception& e) {
        cerr << e.what() << endl;
    }
}

由于您的异常基于 std::exception,并且您覆盖了 virtual const char* what(),因此您将在 catch 子句中获得消息。

【讨论】:

  • (关于编辑建议):为什么要从函数中删除virtual?尽管被覆盖,但它们仍然是虚拟的。而且我认为标记被覆盖的函数仍然是virtual 总是一个很好的指标(虽然不是绝对必要的并且已经用override 关键字标记)
猜你喜欢
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 1970-01-01
  • 2011-08-02
  • 2012-02-06
  • 2016-01-01
  • 1970-01-01
相关资源
最近更新 更多