Hello again! In this video, we are going to look at exception safety. Exception safety means that
code behaves correctly when exceptions are thrown, and obviously that is something we want.
So how do we do it? In C++,
there are three main ways to write exception-safe code.
You can provide the so-called basic exception guarantee: if an exception is thrown during an operation,
no resources will be leaked.
So, for example, if you open a file and an exception is thrown, the file gets closed.
If you allocate memory in an operation and an exception is thrown, the memory is released. And so on.
The strong exception guarantee provides all that, and it also reverts the program to its previous
state, before the operation started.
So it is all as if the operation had never happened.
It was all just a dream :)
And then we can have the no
throw guarantee, which is that we do not throw any exceptions at all.
And if you do not throw any exceptions, then you do not have any problems from dealing with exceptions.
The basic exception guarantee provides the minimum level of exception safety: an operation
will either succeed, or throw an exception.
And if there is an exception, there are no resource leaks. So all operations and functions in the C++
standard library provide this basic guarantee.
With the strong exception, guarantee, an operation will either succeed or have no effect. If
it throws an exception, everything will go back to the same state as it was before the operation.
And that is what is known as transactional semantics.
If you have worked with databases, you may have come across commit and rollback. When you were doing
an update,
if everything succeeds, then you "commit", and the changes are saved in the database.
If something goes wrong, you "roll back" your changes, and the database is left unmodified.
All or references, which you obtained before the operation, will remain valid after
the operation, even if the operation throws an exception.
And all the operations on the standard templates library containers provides this strong exception guarantee.
There are just a couple of cases within search operations where iterators can be invalidated. To provide
the basic exception guarantee,
any resources which are acquired during the operation must be released when an exception is thrown.
So you can either do that manually.
You have a try block where you acquire resources.
For example, allocating memory. And in the catch block, you release the resource - you call delete.
Or alternatively, you can use objects which manage the resource and automatically release it when the
destructor is called.
So that will be when the program jumps out of the try block and calls the destructors for all the objects
in the try
block.
So with string and vector, that will release the memory that is being used by the object.
And for fstream, the destructor will close the file.
So this should make you think of a four-letter word.
No, not that four-letter word!
I am thinking of RAII, but we will come back to that.
Okay, so that is it for this feature.
I will see you next time.
But until then, keep coding!