Defines a type of object to be thrown as exception. It may be used by the implementation to report domain errors, that is, situations where the inputs are outside of the domain on which an operation is defined.
The standard library components do not throw this exception (mathematical functions report domain errors as specified in math_errhandling). Third-party libraries, however, use this. For example, boost.math throws std::domain_error
if boost::math::policies::throw_on_error
is enabled (the default setting).
Inheritance diagram
Contents
- 1 Member functions
- 2 std::domain_error::domain_error
- 2.1 Parameters
- 2.2 Exceptions
- 2.3 Notes
- 3 std::domain_error::operator=
- 3.1 Parameters
- 3.2 Return value
- 3.3 Notes
- 4 Inherited from std::logic_error
- 5 Inherited from std::exception
- 5.1 Member functions
- 5.2 Defect reports
[edit] Member functions
constructs a new domain_error object with the given message (public member function) |
|
replaces the domain_error object (public member function) |
std::domain_error::domain_error
domain_error( const std::string& what_arg ); |
(1) | |
domain_error( const char* what_arg ); |
(2) | |
(3) | ||
domain_error( const domain_error& other ); |
(until C++11) | |
domain_error( const domain_error& other ) noexcept; |
(since C++11) | |
1) Constructs the exception object with what_arg as explanatory string. After construction, std::strcmp(what(), what_arg.c_str()) == 0.
2) Constructs the exception object with what_arg as explanatory string. After construction, std::strcmp(what(), what_arg) == 0.
3) Copy constructor. If *this and other both have dynamic type std::domain_error
then std::strcmp(what(), other.what()) == 0. No exception can be thrown from the copy constructor. (until C++11)
Parameters
what_arg | — | explanatory string |
other | — | another exception object to copy |
Exceptions
Notes
Because copying std::domain_error
is not permitted to throw exceptions, this message is typically stored internally as a separately-allocated reference-counted string. This is also why there is no constructor taking std::string&&
: it would have to copy the content anyway.
Before the resolution of LWG issue 254, the non-copy constructor can only accept std::string. It makes dynamic allocation mandatory in order to construct a std::string object.
After the resolution of LWG issue 471, a derived standard exception class must have a publicly accessible copy constructor. It can be implicitly defined as long as the explanatory strings obtained by what()
are the same for the original object and the copied object.
std::domain_error::operator=
domain_error& operator=( const domain_error& other ); |
(until C++11) | |
domain_error& operator=( const domain_error& other ) noexcept; |
(since C++11) | |
Assigns the contents with those of other. If *this and other both have dynamic type std::domain_error
then std::strcmp(what(), other.what()) == 0 after assignment. No exception can be thrown from the copy assignment operator. (until C++11)
Parameters
other | — | another exception object to assign with |
Return value
*this
Notes
After the resolution of LWG issue 471, a derived standard exception class must have a publicly accessible copy assignment operator. It can be implicitly defined as long as the explanatory strings obtained by what()
are the same for the original object and the copied object.
Inherited from std::logic_error
Inherited from std::exception
Member functions
destroys the exception object (virtual public member function of std::exception ) [edit]
|
|
returns an explanatory string (virtual public member function of std::exception ) [edit]
|
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 254 | C++98 | the constructor accepting const char* was missing | added |
LWG 471 | C++98 | the explanatory strings of std::domain_error ‘scopies were implementation-defined |
they are the same as that of the original std::domain_error object
|
- 1. Инварианты
- 2. Виды исключений
- 3. std::logic_error
- 4. std::invalid_argument
- 5. std::domain_error
- 6. std::length_error
- 7. std::out_of_range
- 8. std::future_error
- 9. std::runtime_error
- 10. std::range_error
- 11. std::overflow_error
- 12. std::underflow_error
- 13. std::system_error
- 14. std::ios_base::failure
- 15. std::bad_typeid
- 16. std::bad_cast
- 17. std::bad_weak_ptr
- 18. std::bad_function_call
- 19. std::bad_alloc
- 20. std::bad_array_new_length
- 21. std::bad_exception
Что такое исключение? Это ситуация, которая не предусмотрена стандартным поведением программы. Например, попытка доступа к элементу в классе Vector (который мы разбирали в статье про
классы
), который не существует. То есть происходит выход за пределы вектора. В данном случае можно воспользоваться исключениями, чтобы прервать выполнение программы. Это необходимо потому, что
-
Как правило в таких случаях, автор класса
Vector
не знает, как пользователь захочет использовать его класс, а также не знает в какой программе этот класс будет использоваться. -
Пользователь класса
Vector
не может всегда контролировать правильность работы этого класса, поэтому ему нужно сообщить о том, что что-то пошло не так.
Для разрешения таких ситуация в C++ можно использовать технику исключений.
Рассмотрим, как написать вызов исключения в случае попытки доступа к элементу по индексу, который не существует в классе Vector.
double& Vector::operator[](int i) { if (i<0 || size()<=i) throw out_of_range{"Vector::operator[]"}; return elem[i]; }Здесь применяется исключение
out_of_range.
Данное исключение определено в заголовочном файле
.
Оператор
throw
передаёт контроль обработчику для исключений типа
out_of_range
в некоторой функции, которая прямо или косвенно вызывает
Vector::operator
. Для того, чтобы обработать исключения необходимо воспользоваться блоком операторов
try catch.
void f(Vector& v) { // ... try { // блок обработки функции с исключением v[v.size()] = 7; // попытка доступа к элементу за пределами вектора } catch (out_of_range) { // ловим ошибку out_of_range // ... обработки ошибки out_of_range ... } // ... }Инварианты
Также блоки
try catch
позволяют производить обработку нескольких различных исключений, что вносит инвариантность в работу механизма исключений C++.Например, класс вектор при создании может получить неправильный размер вектора или не найти свободную память для элементов, которые он будет содержать.
Vector::Vector(int s) { if (s < 0) throw length_error{}; elem = new double[s]; sz = s; }Данный конструктор может выбросить исключение в двух случаях:
-
Если в качестве аргумента
size
будет передано отрицательное значение -
Если оператор
new
не сможет выделить память
length_error
— это стандартный оператор исключений, поскольку библиотека std часто использует данные исключения при своей работе.
Обработка исключений будет выглядеть следующим образом:
void test() { try { Vector v(−27); } catch (std::length_error) { // обработка отрицательного размера вектора } catch (std::bad_alloc) { // обработка ошибки выделения памяти } }Также можно выделить свои собственные исключения.
Виды исключений
Все исключения стандартной библиотеки наследуются от
std::exception.
На данный момент существуют следующие виды исключений:
- logic_error
- invalid_argument
- domain_error
- length_error
- out_of_range
- future_error (C++11)
- runtime_error
- range_error
- overflow_error
- underflow_error
- system_error (C++11)
- ios_base::failure (начиная с C++11)
- bad_typeid
- bad_cast
- bad_weak_ptr (C++11)
- bad_function_call (C++11)
- bad_alloc
- bad_array_new_length (C++11)
- bad_exception
- ios_base::failure (до C++11)
std::logic_error
Исключение определено в заголовочном файле
Определяет тип объекта, который будет брошен как исключение. Он сообщает об ошибках, которые являются следствием неправильной логики в рамках программы, такие как нарушение логической предпосылки или класс инвариантов, которые возможно предотвратить.
Этот класс используется как основа для ошибок, которые могут быть определены только во время выполнения программы.
std::invalid_argument
Исключение определено в заголовочном файле
Наследован от std::logic_error. Определяет исключение, которое должно быть брошено в случае неправильного аргумента.
Например, на MSDN приведён пример, когда в объект класса bitset из стандартной библиотеки
// invalid_arg.cpp // compile with: /EHsc /GR #include <bitset> #include <iostream> using namespace std; int main( ) { try { bitset< 32 > bitset( string( "11001010101100001b100101010110000") ); } catch ( exception &e ) { cerr << "Caught " << e.what( ) << endl; cerr << "Type " << typeid( e ).name( ) << endl; }; } * Output: Caught invalid bitset<N> char Type class std::invalid_argument *В данном примере передаётся неправильная строка, внутри которой имеется символ ‘b’, который будет ошибочным.
std::domain_error
Исключение определено в заголовочном файле
Наследован от std::logic_error. Определяет исключение, которое должно быть брошено в случае если математическая функция не определена для того аргумента, который ей передаётся, например:
std::sqrt(-1)std::length_error
Исключение определено в заголовочном файле
Наследован от std::logic_error. Определяет исключение, которое должно быть броше в том случае, когда осуществляется попытка реализации превышения допустим пределов для объекта. Как это было показано для размера вектора в начале статьи.
std::out_of_range
Исключение определено в заголовочном файле
Наследован от std::logic_error. Определяет исключение, которое должно быть брошено в том случае, когда происходит выход за пределы допустимого диапазона значений объекта. Как это было показано для диапазона значений ветора в начале статьи.
std::future_error
Исключение определено в заголовочном файле
Наследован от std::logic_error. Данное исключение может быть выброшено в том случае, если не удалось выполнить функцию, которая работает в асинхронном режиме и зависит от библиотеки потоков. Это исключение несет код ошибки совместимый с
std::error_code
.std::runtime_error
Исключение определено в заголовочном файле
Является базовым исключением для исключений, которые не могут быть легко предсказаны и должны быть брошены во время выполнения программы.
std::range_error
Исключение определено в заголовочном файле
Исключение используется при ошибках при вычислении значений с плавающей запятой, когда компьютер не может обработать значение, поскольку оно является либо слишком большим, либо слишком маленьким. Если значение является значение интегрального типа, то должны использоваться исключения
underflow_error
или
overflow_error
.std::overflow_error
Исключение определено в заголовочном файле
Исключение используется при ошибках при вычислении значений с плавающей запятой интегрального типа, когда число имеет слишком большое положительное значение, положительную бесконечность, при которой происходит потеря точности, т.е. результат настолько большой, что не может быть представлен числом в формате IEEE754.
std::underflow_error
Исключение определено в заголовочном файле
Исключение используется при ошибках при вычислении значений с плавающей запятой интегрального типа, при которой происходит потеря точности, т.е. результат настолько мал, что не может быть представлен числом в формате IEEE754.
std::system_error
Исключение определено в заголовочном файле
std::system_error
— это тип исключения, которое вызывается различными функциями стандартной библиотеки (как правило, функции, которые взаимодействуют с операционной системой, например, конструктор
std::thread
), при этом исключение имеет соответствующий
std::error_code
.std::ios_base::failure
Исключение определено в заголовочном файле
Отвечает за исключения, которые выбрасываются при ошибках функций ввода вывода.
std::bad_typeid
Исключение определено в заголовочном файле
Исключение этого типа возникает, когда оператор
typeid
применяется к нулевому указателю полиморфного типа.#include <iostream> #include <typeinfo> struct S { // Тип должен быть полиморфным virtual void f(); }; int main() { S* p = nullptr; try { std::cout << typeid(*p).name() << 'n'; } catch(const std::bad_typeid& e) { std::cout << e.what() << 'n'; } }std::bad_cast
Исключение определено в заголовочном файле
Данное исключение возникает в том случае, когда производится попытка каста объекта в тот тип объекта, который не входит с ним отношения наследования.
#include <iostream> #include <typeinfo> struct Foo { virtual ~Foo() {} }; struct Bar { virtual ~Bar() {} }; int main() { Bar b; try { Foo& f = dynamic_cast<Foo&>(b); } catch(const std::bad_cast& e) { std::cout << e.what() << 'n'; } }std::bad_weak_ptr
Исключение определено в заголовочном файле
std::bad_weak_ptr
– тип объекта, генерируемый в качестве исключения конструкторами
std::shared_ptr
, которые принимают
std::weak_ptr
в качестве аргумента, когда
std::weak_ptr
ссылается на уже удаленный объект.#include <memory> #include <iostream> int main() { std::shared_ptr<int> p1(new int(42)); std::weak_ptr<int> wp(p1); p1.reset(); try { std::shared_ptr<int> p2(wp); } catch(const std::bad_weak_ptr& e) { std::cout << e.what() << 'n'; } }std::bad_function_call
Исключение определено в заголовочном файле
Данное исключение генерируется в том случае, если был вызван метод
std::function::operator()
объекта
std::function
, который не получил объекта функции, то есть ему был передан в качестве инициализатора nullptr, например, а объект функции так и не был передан.#include <iostream> #include <functional> int main() { std::function<int()> f = nullptr; try { f(); } catch(const std::bad_function_call& e) { std::cout << e.what() << 'n'; } }std::bad_alloc
Исключение определено в заголовочном файле
Вызывается в том случае, когда не удаётся выделить память.
std::bad_array_new_length
Исключение определено в заголовочном файле
Исключение вызывается в следующих случаях:
- Массив имеет отрицательный размер
- Общий размер нового массива превысил максимальное значение, определяемое реализацией
- Количество элементов инициализации превышает предлагаемое количество инициализирующих элементов
#include <iostream> #include <new> #include <climits> int main() { int negative = -1; int small = 1; int large = INT_MAX; try { new int[negative]; // negative size new int[small]{1,2,3}; // too many initializers new int[large][1000000]; // too large } catch(const std::bad_array_new_length &e) { std::cout << e.what() << 'n'; } }std::bad_exception
Исключение определено в заголовочном файле
std::bad_exception
— это тип исключения в C++, которое выполняется в следующих ситуациях:
- Если нарушается динамическая спецификация исключений
- Если
std::exception_ptr
хранит копию пойманного исключения, и если конструктор копирования объекта исключения поймал current_exception, тогда генерируется исключение захваченных исключений.#include <iostream> #include <exception> #include <stdexcept> void my_unexp() { throw; } void test() throw(std::bad_exception) { throw std::runtime_error("test"); } int main() { std::set_unexpected(my_unexp); try { test(); } catch(const std::bad_exception& e) { std::cerr << "Caught " << e.what() << 'n'; } }
Свойство определяет тип бросаемого объекта как исключение.Он может быть использован реализацией для сообщения об ошибках в домене,т.е.ситуациях,когда входы находятся вне домена,над которым определена операция.
Компоненты стандартной библиотеки не выдают это исключение (математические функции сообщают об ошибках предметной области, как указано в math_errhandling
). Однако сторонние библиотеки используют это. Например, boost.math выдает std::domain_error
, если boost::math::policies::throw_on_error
включен (настройка по умолчанию).
Member functions
(constructor) |
создает новый объект domain_error с заданным сообщением(функция публичного члена) |
operator= |
заменяет объект domain_error (функция публичного члена) |
what |
возвращает пояснительную строку (функция публичного члена) |
std::domain_error::domain_error
domain_error( const std::string& what_arg ); |
(1) | |
domain_error( const char* what_arg ); |
(2) | (since C++11) |
(3) | ||
domain_error( const domain_error& other );
|
(until C++11) | |
domain_error( const domain_error& other ) noexcept; |
(since C++11) |
1-2) Создает объект исключения с what_arg
в качестве пояснительной строки, к которой можно получить доступ через what()
.
3) Конструктор копирования. Если *this
и other
имеют динамический тип std::domain_error
, то std::strcmp(what(), other.what()) == 0
(начиная с C++11).
Parameters
what_arg | — | explanatory string |
other | — | другой объект исключения для копирования |
Exceptions
Notes
Поскольку копирование std::domain_error
не разрешает генерировать исключения, это сообщение обычно хранится внутри как отдельно выделенная строка с подсчетом ссылок. По этой же причине нет конструктора, принимающего std::string&&
: ему бы все равно пришлось копировать содержимое.
std::domain_error::operator=
domain_error& operator=( const domain_error& other ); |
(until C++11) | |
domain_error& operator=( const domain_error& other ) noexcept; |
(since C++11) |
Сопоставляет содержимое с содержимым other
. Если *this
и other
имеют динамический тип std::domain_error
, то std::strcmp(what(), other.what()) == 0
после присваивания (начиная с C++11).
Parameters
other | — | другой объект исключения для присвоения |
Return value
*this
.
std::domain_error::what
virtual const char* what() const throw(); |
(until C++11) | |
virtual const char* what() const noexcept;
|
(since C++11) |
Возвращает пояснительную строку.
Parameters
(none).
Return value
Указатель на завершающуюся нулем строку с пояснительной информацией. Строка подходит для преобразования и отображения в виде std::wstring
. Указатель гарантированно действителен, по крайней мере, до тех пор, пока объект исключения, из которого он получен, не будет уничтожен, или пока не будет вызвана неконстантная функция-член (например, оператор присваивания копии) для объекта исключения.
Notes
Реализации разрешены, но не обязаны переопределять what()
.
Унаследовано от std::logic_error
Наследуется от std :: exception
Member functions
[virtual] |
уничтожает объект исключения (виртуальная публичная функция-член std::exception ) |
[virtual] |
возвращает пояснительную строку (виртуальная публичная функция-член std::exception ) |
C++
-
std::bad_exception::what
Возвращает пояснительную строку.
-
std::current_exception
Если вызывается во время обработки исключений (обычно в пункте catch),перехватывает текущий объект,создавая std::exception_ptr,который содержит либо копию,либо ссылку.
-
std::errc
Скопированное перечисление std::errc определяет значения переносимых условий ошибок,которые соответствуют кодам POSIX.
-
std::make_error_code(std::errc)
Создает значение кода ошибки для перечисления errc. Эквивалентно std::error_code(static_cast<int>(e), std::generic_category()).
Defined in header <stdexcept> |
||
---|---|---|
class domain_error; |
Defines a type of object to be thrown as exception. It may be used by the implementation to report domain errors, that is, situations where the inputs are outside of the domain on which an operation is defined.
The standard library components do not throw this exception (mathematical functions report domain errors as specified in math_errhandling
). Third-party libraries, however, use this. For example, boost.math throws std::domain_error
if boost::math::policies::throw_on_error
is enabled (the default setting).
Inheritance diagram.
Member functions
(constructor) |
constructs a new domain_error object with the given message (public member function) |
operator= |
replaces the domain_error object (public member function) |
what |
returns the explanatory string (public member function) |
std::domain_error::domain_error
domain_error( const std::string& what_arg ); |
(1) | |
domain_error( const char* what_arg ); |
(2) | (since C++11) |
(3) | ||
domain_error( const domain_error& other ); |
(until C++11) | |
domain_error( const domain_error& other ) noexcept; |
(since C++11) |
1-2) Constructs the exception object with what_arg
as explanatory string that can be accessed through what()
.
3) Copy constructor. If *this
and other
both have dynamic type std::domain_error
then std::strcmp(what(), other.what()) == 0
. (since C++11)
Parameters
what_arg | — | explanatory string |
other | — | another exception object to copy |
Exceptions
Notes
Because copying std::domain_error
is not permitted to throw exceptions, this message is typically stored internally as a separately-allocated reference-counted string. This is also why there is no constructor taking std::string&&
: it would have to copy the content anyway.
std::domain_error::operator=
domain_error& operator=( const domain_error& other ); |
(until C++11) | |
domain_error& operator=( const domain_error& other ) noexcept; |
(since C++11) |
Assigns the contents with those of other
. If *this
and other
both have dynamic type std::domain_error
then std::strcmp(what(), other.what()) == 0
after assignment. (since C++11).
Parameters
other | — | another exception object to assign with |
Return value
*this
.
std::domain_error::what
virtual const char* what() const throw(); |
(until C++11) | |
virtual const char* what() const noexcept; |
(since C++11) |
Returns the explanatory string.
Parameters
(none).
Return value
Pointer to a null-terminated string with explanatory information. The string is suitable for conversion and display as a std::wstring
. The pointer is guaranteed to be valid at least until the exception object from which it is obtained is destroyed, or until a non-const member function (e.g. copy assignment operator) on the exception object is called.
Notes
Implementations are allowed but not required to override what()
.
Inherited from std::logic_error
Inherited from std::exception
Member functions
[virtual] |
destroys the exception object (virtual public member function of std::exception ) |
[virtual] |
returns an explanatory string (virtual public member function of std::exception ) |