Does C++ support 'finally' blocks?
What is the RAII idiom?
What is the difference between C++'s RAII idiom and C#'s 'using' statement?
Does C++ support 'finally' blocks?
What is the RAII idiom?
What is the difference between C++'s RAII idiom and C#'s 'using' statement?
Not really, but you can emulate them to some extend, for example:
Note that the finally-block might itself throw an exception before the original exception is re-thrown, thereby discarding the original exception. This is the exact same behavior as in a Java finally-block. Also, you cannot use
return
inside the try&catch blocks.As many people have stated, the solution is to use C++11 features to avoid finally blocks. One of the features is
unique_ptr
.Here is Mephane's answer written using RAII patterns.
Some more introduction to using unique_ptr with C++ Standard Library containers is here
I came up with a
finally
macro that can be used almost like¹ thefinally
keyword in Java; it makes use ofstd::exception_ptr
and friends, lambda functions andstd::promise
, so it requiresC++11
or above; it also makes use of the compound statement expression GCC extension, which is also supported by clang.WARNING: an earlier version of this answer used a different implementation of the concept with many more limitations.
First, let's define a helper class.
Then there's the actual macro.
It can be used like this:
The use of
std::promise
makes it very easy to implement, but it probably also introduces quite a bit of unneeded overhead which could be avoided by reimplementing only the needed functionalities fromstd::promise
.¹ CAVEAT: there are a few things that don't work quite like the java version of
finally
. Off the top of my head:break
statement from within thetry
andcatch()
's blocks, since they live within a lambda function;catch()
block after thetry
: it's a C++ requirement;try
andcatch()'s
blocks, compilation will fail because thefinally
macro will expand to code that will want to return avoid
. This could be, err, avoided by having afinally_noreturn
macro of sorts.All in all, I don't know if I'd ever use this stuff myself, but it was fun playing with it. :)
No, C++ does not support 'finally' blocks. The reason is that C++ instead supports RAII: "Resource Acquisition Is Initialization" -- a poor name† for a really useful concept.
The idea is that an object's destructor is responsible for freeing resources. When the object has automatic storage duration, the object's destructor will be called when the block in which it was created exits -- even when that block is exited in the presence of an exception. Here is Bjarne Stroustrup's explanation of the topic.
A common use for RAII is locking a mutex:
RAII also simplifies using objects as members of other classes. When the owning class' is destructed, the resource managed by the RAII class gets released because the destructor for the RAII-managed class gets called as a result. This means that when you use RAII for all members in a class that manage resources, you can get away with using a very simple, maybe even the default, destructor for the owner class since it doesn't need to manually manage its member resource lifetimes. (Thanks to Mike B for pointing this out.)
For those familliar with C# or VB.NET, you may recognize that RAII is similar to .NET deterministic destruction using IDisposable and 'using' statements. Indeed, the two methods are very similar. The main difference is that RAII will deterministically release any type of resource -- including memory. When implementing IDisposable in .NET (even the .NET language C++/CLI), resources will be deterministically released except for memory. In .NET, memory is not deterministically released; memory is only released during garbage collection cycles.
† Some people believe that "Destruction is Resource Relinquishment" is a more accurate name for the RAII idiom.