Evgenii Legotckoi
Evgenii LegotckoiOct. 15, 2017, 5:31 p.m.

C++ - Tutorial 011. Exceptions

What is an exception? This is a situation that is not provided by the standard behavior of the program. For example, an attempt to access an element in the Vector class (which we discussed in the article about classes ), which does not exist. That is, there is a way out of the vector. In this case, you can use exceptions to interrupt the execution of the program. This is necessary because

  • As a rule in such cases, the author of the Vector class does not know how the user wants to use its class, and also does not know in which program this class will be used.
  • A user of the Vector class can not always control the correctness of this class, so he needs to report that something went wrong.

To resolve such a situation in C ++, you can use the exception technique.


Consider how to write an exception call when an element is attempted to access an element that does not exist in the Vector class.

double& Vector::operator[](int i)
{
    if (i<0 || size()<=i) throw out_of_range{"Vector::operator[]"};
    return elem[i];
}

Here, the out_of_range exception is used. This exception is defined in the header file.

The throw statement passes control to the handler for out_of_range exceptions in some function that directly or indirectly calls Vector::operator . In order to handle exceptions, you must use the try catch statement block.

void f(Vector& v)
{
    // ...
    try { // function block with exception
        v[v.size()] = 7; // attempt to access an element outside the vector
    }
    catch (out_of_range) { // catch the error out_of_range
        // ... error handling out_of_range ...
    }
    // ...
}

Invariants

Also, try catch blocks allow processing of several different exceptions, which introduces invariance into the operation of the C ++ exception mechanism....

For example, a vector class can create an invalid vector size when it is created, or it can not find free memory for the elements it will contain.

Vector::Vector(int s)
{
    if (s < 0) throw length_error{};
    elem = new double[s];
    sz = s;
}

This constructor can throw an exception in two cases:

  • If a negative value is passed as the size argument
  • If the operator new can not allocate memory

length_error - This is the standard exception operator, because the std library often uses exception data in its work.

Exception handling will look like this:

void test()
{
    try {
        Vector v(−27);
    }
    catch (std::length_error) {
        // processing of negative vector size
    }
    catch (std::bad_alloc) {
        // memory allocation error handling
    }
}

You can also create your own exceptions.

Types of Exceptions

All exceptions to the standard library are inherited from std::exception.

At the moment, there are the following types of exceptions:

  • 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

An exception is defined in the header file

Defines the type of object that will be thrown as an exception. He reports errors that are the result of incorrect logic within the program, such as a violation of a logical prerequisite or a class of invariants that can be prevented.

This class is used as the basis for errors that can only be determined at run-time.

std::invalid_argument

An exception is defined in the header file

Inherited from std::logic_error. Defines an exception that must be thrown in case of an incorrect argument.

For example, MSDN gives an example when an object of the bitset class from the standard library

// 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  
*\ 

In this example, an incorrect string is passed, inside of which there is a character 'b', which will be erroneous.

std::domain_error

An exception is defined in the header file

Inherited from std::logic_error. Defines an exception that must be thrown if the mathematical function is not defined for the argument that is passed to it, for example:

std::sqrt(-1)

std::length_error

An exception is defined in the header file

Inherited from std::logic_error. Specifies the exception that must be given to the brochete when an attempt is made to implement an excess of the allowed limits for the object. As was shown for the vector size at the beginning of theи.

std::out_of_range

An exception is defined in the header file

Inherited from std::logic_error. Defines an exception that must be thrown when it is outside the allowed range of object values. As it was shown for the range of values of the wind at the beginning of the article.

std::future_error

An exception is defined in the header file

Inherited from std::logic_error. This exception can be thrown in the event that the function that operates in asynchronous mode and depends on the thread library failed. This exception has an error code that is compatible with std::error_code.

std::runtime_error

An exception is defined in the header file

This is the basic exception for exceptions that can not be easily predicted and must be thrown during program execution.

std::range_error

An exception is defined in the header file

The exception is used for errors when computing floating-point values when the computer can not process the value, because it is either too large or too small. If the value is an integral type, then underflow_error or overflow_error should be used.

std::overflow_error

An exception is defined in the header file

The exception is used for errors in the calculation of floating point values of the integral type, when the number is too large a positive value.

std::underflow_error

An exception is defined in the header file

The exception is used for errors when calculating floating point values of an integral type when the number is too large a negative value.

std::system_error

An exception is defined in the header file

std::system_error is an exception type that is called by various functions of the standard library (usually functions that interact with the operating system, for example, the std::thread constructor), with the exception having the corresponding std::error_code .

std::ios_base::failure

An exception is defined in the header file

It is responsible for exceptions that are thrown when I / O functions fail.

std::bad_typeid

An exception is defined in the header file

An exception of this type occurs when the typeid operator is applied to a null pointer of a polymorphic type.

#include <iostream>
#include <typeinfo>

struct S { // The type must be polymorphic
    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

An exception is defined in the header file

This exception occurs when an object cast is attempted in that type of object that does not include inheritance relations with it.

#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

An exception is defined in the header file

std::bad_weak_ptr - the type of the object, generated as an exception by the constructors std::shared_ptr, which accept std::weak_ptr as an argument when std::weak_ptr refers to an already deleted object.

#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

An exception is defined in the header file

This exception is generated if the std::function() method of the std::function object was called, which did not receive the function object, that is, it was passed as the initializer nullptr, for example, and the function object was not was transferred.

#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

An exception is defined in the header file

Called when the memory can not be allocated.

std::bad_array_new_length

An exception is defined in the header file

An exception is thrown in the following cases:

  1. The array has a negative size
  2. The total size of the new array exceeded the maximum value determined by the implementation
  3. The number of initialization elements exceeds the suggested number of initializers
#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

An exception is defined in the header file

std::bad_exception - This is an exception type in C ++ that is executed in the following situations:

  1. If the dynamic exception specification is violated
  2. If std::exception_ptr stores a copy of the caught exception, and if the copy constructor of the exception object caught the current_exception, then an exception is thrown for exceptions.
#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';
    }
}
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

P
  • Oct. 15, 2017, 11 p.m.

std::underflow_error - это не "число имеет слишком большое отрицательное значение", а потеря точности при вычислениях, т.е. результат настолько мал, что не может быть представлен числом в формате IEEE754

Evgenii Legotckoi
  • Oct. 16, 2017, 2:46 a.m.

Спасибо. Дополнил.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
AD

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:20points,
  • Rating points-10
Last comments
Evgenii Legotckoi
Evgenii LegotckoiNov. 1, 2024, 12:37 a.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 6:19 p.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 5:51 p.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 9:02 p.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrFeb. 9, 2024, 5:43 a.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 25, 2024, 1:11 a.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 5:04 p.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 1:49 p.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 7:10 p.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks