1

我为我的 cs 类分配的任务是创建两个继承自 std::logic_error 的自定义异常类:OverflowingSwimmingPoolException 和 UnderflowingSwimmingPoolException。当尝试非法操作时,创建并抛出自定义异常,而不仅仅是打印错误消息。在驱动程序代码中包含 try...catch 块以捕获任何异常。

这是我的头文件的一部分:

    #ifndef SWIMMINGPOOL_H
    #define SWIMMINGPOOL_H
    #include <stdexcept>
    #include <iostream>
    using namespace std;



 namespace cs52
  {
          class OverflowingSwimmingPoolException: public logic_error
  {

    OverflowingSwimmingPoolException (){};

};

class UnderflowingSwimmingPoolException: public logic_error
{

    UnderflowingSwimmingPoolException(){};
};

这是编译器在构造函数所在的行上说的:“cs52::UnderflowingSwimmingPoolException”的构造函数必须显式初始化没有默认构造函数的基类“std::logic_error”。

这就是我的实现文件中的内容:

    #include "SwimmingPool.h"
    #include <stdexcept>
    #include <iostream>
     using namespace std;



     namespace cs52
     {       
      SwimmingPool operator +(const SwimmingPool& pool1, const SwimmingPool&         pool2) throw (OverflowingSwimmingPoolException, UnderflowingSwimmingPoolException)
{
    SwimmingPool temp;
    temp.mySize = pool1.mySize+pool2.mySize;
    temp.myContents = pool1.myContents+pool2.myContents;
    if (temp.myContents>temp.mySize)
   throw OverflowingSwimmingPoolException();
    return temp;
}
SwimmingPool operator -(const SwimmingPool& pool1, const SwimmingPool& pool2) throw (OverflowingSwimmingPoolException, UnderflowingSwimmingPoolException)
{
    SwimmingPool temp;
    temp.mySize= pool1.mySize-pool2.mySize;
    temp.myContents= pool1.myContents-pool2.myContents;
    if (temp.myContents>temp.mySize)
        throw OverflowingSwimmingPoolException();
    if (temp.myContents<0 || temp.mySize<0)
        throw UnderflowingSwimmingPoolException();
    return temp;
}
}

编译器在我抛出异常类的行中显示错误。它说:调用类 cs53:OverflowingSwimmimgPoolException 的私有构造函数。

我的驱动程序文件的一部分应该是这样的:

   using namespace cs52;
   try {
    SwimmingPool badPool = smallOne - bigOne;
    cout << "This should never happen..." << endl;
    } 
    catch( UnderflowingSwimmingPoolException uspe ) {
    cout << "working..." << endl;
    } 
    catch( OverflowingSwimmingPoolException uspe ) {
    cout << "This should never happen..." << endl;
    }

我刚刚开始编写代码,所以我不太了解已经在库中创建的 std::logic_error 之类的类是如何工作的。

4

3 回答 3

1

在派生异常的构造函数中,您必须调用基类的构造函数,该构造函数接受一个包含一些错误文本的字符串,如下所示:

OverflowingSwimmingPoolException ()
  : std::logic_error("It's all gone horribly wrong!")
{};

当您调用捕获的异常时,这将被返回what()(假设您没有用不同的行为覆盖它;但不要这样做):

try {
    // ...
} catch (std::exception const& e) {
    std::cerr << e.what() << '\n'; // Prints "It's all gone horribly wrong!"
}

异常类型的接口为此目的采用字符串是很常见的,但当然对于您自己的异常类型,您不必这样做。

请注意,如果您catch使用基类的异常,请确保您通过引用(或引用到- const)捕获,以避免对象切片

于 2017-02-06T07:40:59.030 回答
1

错误非常清楚,与逻辑或何时、何地以及如何抛出异常无关。它只是关于异常类本身和构造函数。

请注意错误是如何说明您必须初始化父类的?您可以使用构造函数初始化列表来做到这一点,例如

OverflowingSwimmingPoolException ()
    : std::logic_error("Some error message")
{}

std::logic_error初始化中的错误消息是what函数将报告的内容。

于 2017-02-06T07:41:17.047 回答
0

编译器消息“必须显式初始化没有默认构造函数的基类'std::logic_error'”是因为std::logic_error在初始化期间需要一个参数。具体来说,它需要一个字符串。例如:

class my_exception: public std::logic_error {
    my_exception() { };
}

...不会工作,但是...

class my_exception: public std::logic_error {
    my_exception(const char* what): std::logic_error(what) { };
}

...会因为没有构造函数std::logic_error::logic_error()但有一个std::logic_error::logic_error(const char*)

如果您想what为特定异常类静态指定异常“原因”(由 给出),您可以在构造过程中指定它,例如...

class my_exception: public std::logic_error {
    my_exception(): std::logic_error("Oh No!") { };
}

所有标准异常都继承自std::exception期望异常原因。后来这个理由可以用类似...

try {
    throw my_exception();
} catch (const std::exception& e) { // << because you inherited this class
    std::cerr << "error: " << e.what() << std::endl;
}

...这将打印“错误:哦,不!” 使用前面的例子。

具体而言,请参阅std::logic_errorstd::exception了解更多详细信息。

于 2017-02-06T07:42:41.203 回答