Std:: исключение подкласс, переменная члена строки
Следующий код работает очень хорошо:
#include <exception>
using namespace std;
class FileException : public exception { // error occurs here
int _error;
// string _error; <-- this would cause the error
public:
FileException(int error);
// FileException(string error);
const char* what() const throw();
};
Но как только я изменяю тип _error
на строку, возникает следующая ошибка компиляции:
Спецификация исключения для функции переопределения более слабая, чем базовая версия
Ответы
Ответ 1
Деструктор std::string
не является не-броском, что приводит к неявному деструктору FileException
. Но деструктор std::exception
не-throw, поэтому есть ошибка компилятора.
Вы можете объявить явный деструктор no-throw:
virtual ~FileException() throw() {}
или просто наследуйте от std::runtime_error
вместо std::exception
, у которого есть конструктор, который принимает вход std::string
.
Ответ 2
Упростить с помощью:
// Derive from std::runtime_error rather than std::exception
// std::runtime_error (unlike std::exception) accepts a string as an argument that will
// be used as the error message.
//
// Note: Some versions of MSVC have a non standard std::exception that accepts a string
// Do not rely on this.
class FileException : public std::runtime_error
{
public:
// Pass error msg by const reference.
FileException(std::string const& error)
// Pass the error to the standard exception
: std::runtime_error(error)
{}
// what() is defined in std::runtime_error to do what is correct
};
Ответ 3
Я одобряю вышеуказанный метод,
но g++, похоже, жалуется, если
конструктор по умолчанию отсутствует.
Следующее дополнение делает работу:
using namespace std;
class MyException : public runtime_error {
public:
/* add the following line: */
MyException() : runtime_error("MyException") { } // default constructor
MyException( string const& error ) : runtime_error(error) { } // ctor w/string
};
Кроме того, список исключений легко создается:
MyException FileNotFound ( "File Not Found" );
MyException ReadOnly ( "ReadOnly" );
MyException Unkown ( "Unknown" );
...
throw FileNotFound;
...
при перехвате этих исключений, если вам не нужна специфика, поймайте их в общих чертах:
catch( runtime_error re) { cout << "Runtime Error: " << re.what() << endl; ... }
Так как все MyExceptions деактируют с runtime_error, это захватывает их всех и
вы также не пропустите другие ошибки времени выполнения из системы.
catch( exception e) { cout << "exception: " << e.what() << endl; ... }
ловит их все.
В С++ вы также можете бросать и захватывать любые типы (int, boolean, указатели и т.д.). Иногда это проще
просто бросить/поймать строку или int внутри функционального блока.
Несколько классов должны только бросать и улавливать стандартные исключения библиотеки кода и их подклассы (и все одинаково), однако, в основном, для согласованности и обслуживания, но также потому, что компиляторы С++ знают, как оптимизировать механизмы исключения и связи для их, и может генерировать интеллектуальные предупреждения и ошибки о них, ослабляя отладки.
"Ошибка:" 0x137F "для ребята IBM, а не" третий парень в проекте в этом году "...