невозможно создать два пользовательских класса исключений, наследуемых от std :: logic_error

Мое назначение для моего класса 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, которые уже созданы в библиотеках.

1

Решение

Ошибка вполне понятна и не имеет ничего общего с логикой или когда, где и как вы выкидываете исключения. Это касается только самих классов исключений и конструктора.

Обратите внимание, как ошибка говорит о том, что вы должны инициализировать родительский класс? Вы можете сделать это с помощью списка инициализатора конструктора, например, например.

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

Сообщение об ошибке в std::logic_error инициализация является то, что what Функция сообщит.

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), избежать нарезка объектов.

1

Сообщение компилятора «должно явно инициализировать базовый класс» 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;
}

… который напечатал бы «ошибка: О, нет!» используя предыдущий пример.

В частности, см. станд :: logic_error станд :: исключение Больше подробностей.

0
По вопросам рекламы [email protected]