我的cs类的任务是创建两个继承自std::logic_error的自定义异常类:OverflowingSwimmingPoolException和UnderflowingSwimmingPoolException。尝试非法操作时,请创建并引发自定义异常,而不仅仅是打印错误消息。 包括尝试...捕获驱动程序代码中的块以捕获任何异常。
这是我的头文件的一部分:
#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 等类是如何工作的。
错误非常明显,与逻辑或何时、何地以及如何抛出异常无关。它只与异常类本身和构造函数有关。
注意错误如何说你必须初始化父类?您可以使用构造函数初始值设定项列表来执行此操作,例如
OverflowingSwimmingPoolException ()
: std::logic_error("Some error message")
{}
std::logic_error
初始化中的错误消息是what
函数将报告的内容。
在派生异常的构造函数中,必须调用基类的构造函数,基类采用包含一些错误文本的字符串,如下所示:
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
)捕获,以避免对象切片。
编译器消息"必须显式初始化没有默认构造函数的基类'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_error an std::exception 了解更多细节。