Click here to Skip to main content
15,850,753 members
Articles / Programming Languages / C++11
Tip/Trick

"finally" clause in C++

Rate me:
Please Sign up or sign in to vote.
4.87/5 (6 votes)
15 Oct 2012CPOL2 min read 51.2K   10   10
finally like clause in C++

Introduction

This article aims to help a programmer who has the need to use "finally" like clause (like in Java) in C++.

Background

There are many cases where such need for finally clause arises, mostly as I can see it, it always happen when a programmer uses a third party or legacy "C oriented" library that deals with resources in a procedural way like open/close file or connect/disconnect a service.

For example, MFC library solves the problem with the introduction of wrapper classes like CWaitCursor, where the cursor is a resource reclaimed back on destruction of the object. The destruction of the object is deterministic and happens on the event of getting out of scope (block end).

What I'm going to show is a solution for an already existing code that needs to be more deterministic and clean, but yet written in a procedural way.

Another reason to use this "finally" like construct is for external resources that should be reclaimed no matter what happened after they were successfully claimed. For example, deterministic log-out of a remote service no matter what happens after a successful log-in to that service. That way prevents the remote dangling service from waiting for a log-out until some time-out routine will close the remote socket...

This solution is not a replacement for a superior design like using RAII (Resource Acquisition Is Initialization), see "Why doesn't C++ provide a "finally" construct?".

For beginners, I strongly suggest to read briefly the following items in the C++ reference:

  1. Lambda Functions in C++11 - the Definitive Guide
  2. Function objects
  3. std::function
  4. std::bind

It is possible to use the example ahead without deep knowledge of what is lambda or what is function object.

Using the Code

The code will run only on C++11 compiler and maybe some C++0x compilers!

For Beginners

It is very easy to use:

C++
FILE *file = fopen("test","w");

finally close_the_file([&]{
    cout << "Finally you close the file." << endl;
    fclose(file);
});

The [&] {...} is the code I suspect is not well understood for beginners, but it doesn't matter, as long as you accept the "unreadable" set of brackets, everything should be OK.

Let's explain:

  1. Opening a file the C way using stdio library, this is an old way of using files, but it is used here for the sake of the explanation. I consider the file opening as successful!
  2. Next line, there is a declaration of object named close_the_file of a class finally and then there is lambda expression that should run on the event of exiting the scope. basically you can copy and paste the class finally (see ahead) and put somewhere in one of your libraries headers for later use.

The "finally" Class

The finally class provides a means of running commands upon leaving the block by using the destructor of the class.

C++
class finally
{
    std::function<void(void)> functor;
public:
    finally(const std::function<void(void)> &functor) : functor(functor) {}
    ~finally()
    {
        functor();
    }
};

Example

Somehow the example file hasn't been uploaded so I decided to write a little example just to show how it works. Try this:

C++
try {
    cout << "Open a file" << endl;
    FILE *file = fopen("test","w");

    finally close_the_file([&]{
        cout << "Finally you close the file." << endl;
        fclose(file);
    });

    cout << "do something before exception" << endl;

    throw("Some exception");

    cout << "do something after exception!?" << endl;
}
catch(char *ex)
{
    cout << ex << endl;
}
catch(...)
{
    ; //do nothing
}

History

  1. First revision
  2. Alternative example to the example file

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Shmuel Zang21-Jul-21 22:39
Shmuel Zang21-Jul-21 22:39 
SuggestionBrilliant Idea! Thanks! Pin
Member 1057449910-Jan-15 10:55
Member 1057449910-Jan-15 10:55 
GeneralMy vote of 5 Pin
magicpapacy22-Oct-12 17:27
magicpapacy22-Oct-12 17:27 
GeneralMy vote of 4 Pin
kosmoh16-Oct-12 8:09
kosmoh16-Oct-12 8:09 
GeneralRe: My vote of 4 Pin
Cpp For All16-Oct-12 22:06
Cpp For All16-Oct-12 22:06 
GeneralRe: My vote of 4 Pin
kosmoh17-Oct-12 7:53
kosmoh17-Oct-12 7:53 
Questionfinally? Pin
Selvin15-Oct-12 16:11
Selvin15-Oct-12 16:11 
AnswerRe: finally? Pin
Cpp For All15-Oct-12 21:09
Cpp For All15-Oct-12 21:09 
GeneralRe: finally? Pin
Selvin15-Oct-12 22:50
Selvin15-Oct-12 22:50 
GeneralRe: finally? Pin
Cpp For All16-Oct-12 0:11
Cpp For All16-Oct-12 0:11 
It imitate the behavior of other languages finally. That is, it guaranties to run set of instruction in case of getting out of scope. it saves the need to write the code twice, once in catch clause and once after catch clause.

There is no way for me to change the C++ language to have the look and feel of other languages. However, the fact that it is possible to have deterministic running of code at the end of scope makes the need for a "nice" finally clause after catch clause even less important.

The interesting side effect of having the finally-object (in the example) as opposed to a finally-clause (in other languages) after resource acquisition makes it much easier to maintain, you don't have to go further few lines ahead, but that is only a matter of taste of course. most important is deterministic behavior in procedural code, behavior that is well achieved in this example.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.