Click here to Skip to main content
11,432,427 members (65,513 online)
Click here to Skip to main content

"finally" clause in C++

, 15 Oct 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
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:

    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.

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:

	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)

Share

About the Author

Cpp For All

United States United States
No Biography provided

Comments and Discussions

 
SuggestionBrilliant Idea! Thanks! Pin
Member 1057449910-Jan-15 10:55
memberMember 1057449910-Jan-15 10:55 
GeneralMy vote of 5 Pin
magicpapacy22-Oct-12 17:27
membermagicpapacy22-Oct-12 17:27 
GeneralMy vote of 4 Pin
kosmoh16-Oct-12 8:09
memberkosmoh16-Oct-12 8:09 
GeneralRe: My vote of 4 Pin
Cpp For All16-Oct-12 22:06
memberCpp For All16-Oct-12 22:06 
Thank you for your vote.
I wrote almost exactly what you wrote here and let me quote myself: "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?'."
Having that said, I don't think that it has no application, there are places were it comes in handy, and those places are exactly:
1. The places where you have to decide whether to pay the price of extra wrapper class code around an old C API or or just use this little utility.
2. Or the places where you'll have to write twice (or more) the same code, once inside the catch clause and once outside.
GeneralRe: My vote of 4 Pin
kosmoh17-Oct-12 7:53
memberkosmoh17-Oct-12 7:53 
Questionfinally? Pin
Selvin15-Oct-12 16:11
memberSelvin15-Oct-12 16:11 
AnswerRe: finally? Pin
Cpp For All15-Oct-12 21:09
memberCpp For All15-Oct-12 21:09 
GeneralRe: finally? Pin
Selvin15-Oct-12 22:50
memberSelvin15-Oct-12 22:50 
GeneralRe: finally? Pin
Cpp For All16-Oct-12 0:11
memberCpp For All16-Oct-12 0:11 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150428.2 | Last Updated 16 Oct 2012
Article Copyright 2012 by Cpp For All
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid