473,386 Members | 2,114 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

try...finally semantics

Hi all,

I just needed some kind of try...finally semantics in a method and was
wondering how to do this "the best way" -- there were two alternatives
which came to my mind:

1) RAII:

void A::method()
{
// Stuff here

// This is the "try...finally"
{
class Finally
{
private:
A& me;
public:
inline Finally(A& m)
: me(m)
{}
inline ~Finally()
{
me.foo=bar;
me.doSomething();
}
} finally(*this);
// Do the throwing stuff
}

// Stuff here
}

2) Catch and rethrow:

void A::method()
{
// Stuff here

#define DO_FINALLY \
foo=bar; \
doSomething();
try
{
// throwing stuff
} catch(...)
{
DO_FINALLY
throw;
}
DO_FINALLY
#undef DO_FINALLY

// Stuff here
}

Of course the RAII thing is "really" like try...finally, as for instance
an early return is caught, too, but the same is not true for 2); and 1)
seems much "cleaner" to me. However, there is some amount of bloat in
1) which seems to make the code a bit unreadable for me.

I believe most C++ programmers must have had a need for try...finally
functionality at some point, and I'd like to know how you solved it /
how you would recommend to solve it. Is there maybe some way I did not
think about?

Thanks,
Daniel

--
Got two Dear-Daniel-Instant Messages
by MSN, associate ICQ with stress--so
please use good, old E-MAIL!
Aug 25 '07 #1
8 2184
Daniel Kraft wrote:
Hi all,

I just needed some kind of try...finally semantics in a method and was
wondering how to do this "the best way" -- there were two alternatives
which came to my mind:

1) RAII:

void A::method()
{
// Stuff here

// This is the "try...finally"
{
class Finally
{
private:
A& me;
public:
inline Finally(A& m)
: me(m)
{}
inline ~Finally()
{
me.foo=bar;
me.doSomething();
}
} finally(*this);
// Do the throwing stuff
}

// Stuff here
}

2) Catch and rethrow:

void A::method()
{
// Stuff here

#define DO_FINALLY \
foo=bar; \
doSomething();
try
{
// throwing stuff
} catch(...)
{
DO_FINALLY
throw;
}
DO_FINALLY
#undef DO_FINALLY

// Stuff here
}

Of course the RAII thing is "really" like try...finally, as for instance
an early return is caught, too, but the same is not true for 2); and 1)
seems much "cleaner" to me. However, there is some amount of bloat in
1) which seems to make the code a bit unreadable for me.

I believe most C++ programmers must have had a need for try...finally
functionality at some point, and I'd like to know how you solved it /
how you would recommend to solve it. Is there maybe some way I did not
think about?
Usually, if your classes are properly designed with a destructor that cleans
up, you get RAII implicitly and there is no need for 'finally'. Dynamically
allocated objects can be handled with std::auto_ptr if you don't already
use some type of shared pointer.
Aug 25 '07 #2
>I believe most C++ programmers must have had a need for try...finally
>functionality at some point, and I'd like to know how you solved it /
how you would recommend to solve it. Is there maybe some way I did not
think about?

Usually, if your classes are properly designed with a destructor that cleans
up, you get RAII implicitly and there is no need for 'finally'. Dynamically
allocated objects can be handled with std::auto_ptr if you don't already
use some type of shared pointer.
Yes, of course, this is useful for most of the needs; but every once in
a while I need some kind of clean-up inside a method other than just
deleting resources and without the whole object being destroyed; for
instance:

void A::foo()
{
obj.setSomeFlag(true);
// Do something
obj.setSomeFlag(false);
}

Now I want to set the flag back to false on every occasion, even if an
exception is thrown in between.

Yours,
Daniel

--
Got two Dear-Daniel-Instant Messages
by MSN, associate ICQ with stress--so
please use good, old E-MAIL!
Aug 25 '07 #3
On Sat, 25 Aug 2007 10:19:42 +0000, Daniel Kraft <d@domob.euwrote:
>every once in
a while I need some kind of clean-up inside a method other than just
deleting resources and without the whole object being destroyed; for
instance:

void A::foo()
{
obj.setSomeFlag(true);
// Do something
obj.setSomeFlag(false);
}

Now I want to set the flag back to false on every occasion, even if an
exception is thrown in between.
What about:

void A::foo()
{
SetSomeFlag objFlag(obj, true);
// Do something

} // RAII resets flag here

If you still want a 'finally' in C++ look for 'scopeguard'.
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Aug 25 '07 #4
Daniel Kraft wrote:
>>I believe most C++ programmers must have had a need for try...finally
functionality at some point, and I'd like to know how you solved it /
how you would recommend to solve it. Is there maybe some way I did not
think about?

Usually, if your classes are properly designed with a destructor that
cleans
up, you get RAII implicitly and there is no need for 'finally'.
Dynamically
allocated objects can be handled with std::auto_ptr if you don't already
use some type of shared pointer.

Yes, of course, this is useful for most of the needs; but every once in
a while I need some kind of clean-up inside a method other than just
deleting resources and without the whole object being destroyed; for
instance:

void A::foo()
{
obj.setSomeFlag(true);
// Do something
obj.setSomeFlag(false);
}

template <typename T>
class FlagSetter
{
T & m_obj;
// don't allow copy or assignment
AFlagSetter & operator=( const AFlagSetter & );
AFlagSetter( const AFlagSetter & );

public:

AFlagSetter( T & i_obj )
: m_obj( i_obj )
{
m_obj.setSomeFlag(true);
}

~AFlagSetter()
{
m_obj.setSomeFlag(false);
}
};
void A::foo()
{
FlagSetter<objTypel_setter( obj );
// Do something
// - automagically happens ... obj.setSomeFlag(false);
}
>
Now I want to set the flag back to false on every occasion, even if an
exception is thrown in between.
You can create a more generic system than I showed above that would
allow you to provide different methods to start/end. If you want a
finally type functionality, this is the way to do it with C++.

Aug 25 '07 #5
>Yes, of course, this is useful for most of the needs; but every once
>in a while I need some kind of clean-up inside a method other than
just deleting resources and without the whole object being destroyed;
for instance:

void A::foo()
{
obj.setSomeFlag(true);
// Do something
obj.setSomeFlag(false);
}


template <typename T>
class FlagSetter
{
T & m_obj;
// don't allow copy or assignment
AFlagSetter & operator=( const AFlagSetter & );
AFlagSetter( const AFlagSetter & );

public:

AFlagSetter( T & i_obj )
: m_obj( i_obj )
{
m_obj.setSomeFlag(true);
}

~AFlagSetter()
{
m_obj.setSomeFlag(false);
}
};
void A::foo()
{
FlagSetter<objTypel_setter( obj );
// Do something
// - automagically happens ... obj.setSomeFlag(false);
}

You can create a more generic system than I showed above that would
allow you to provide different methods to start/end. If you want a
finally type functionality, this is the way to do it with C++.
This is actually how I do it at the moment--using a class local to my
method similar to the one above; but as setting a flag was only an
example of one specific need for such a functionality, I always have to
implement such a class for every case (maybe once closures are available
this can be done with a generic class but up to now I did not find a
generic way for every situation; using a functor object just has the
same verbosity when defining this object).

Which of course works--my point was just I find those "clutter"
associated with defining the class, the constructor, initializing the
reference to my enclosing class and so on a bit confusing and negative
to readability to my code.

But it seems there is no better method, right?

Yours,
Daniel

--
Got two Dear-Daniel-Instant Messages
by MSN, associate ICQ with stress--so
please use good, old E-MAIL!
Aug 25 '07 #6
Daniel Kraft wrote:
.....
>
But it seems there is no better method, right?

Think like this: "creating a new class is a low threshold thing to do in
C++".

You may be able to make things by using some template magic. I would
need to know more specifically to see if there is some way of removing
"clutter". Having said that, there probably isn't too much clutter to
worry about when you look at it a bit closer.
Aug 25 '07 #7
>But it seems there is no better method, right?
>

Think like this: "creating a new class is a low threshold thing to do in
C++".

You may be able to make things by using some template magic. I would
need to know more specifically to see if there is some way of removing
"clutter". Having said that, there probably isn't too much clutter to
worry about when you look at it a bit closer.
Yeah, probably you are right ;)
Thank you!
Daniel

--
Got two Dear-Daniel-Instant Messages
by MSN, associate ICQ with stress--so
please use good, old E-MAIL!
Aug 25 '07 #8
Hi!

Daniel Kraft schrieb:
void A::foo()
{
obj.setSomeFlag(true);
// Do something
obj.setSomeFlag(false);
}

Now I want to set the flag back to false on every occasion, even if an
exception is thrown in between.
Just an idea ;) :

using namespace boost::lambda;
using boost::shared_ptr;

const shared_ptr<boolresetFlag(&obj.flag, *_1 = false);
....

or:

const shared_ptr<boolresetFlag(&obj, bind(
&Obj::setSomeFlag,
_1,
false
));
....

Frank
Aug 25 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: David Stockwell | last post by:
In referring to my copy of the python bible, it tells me I can't use all three items 'try' except and finally. I can use the t/f or t/e combinations though What combination can i use if i want...
26
by: djw | last post by:
Hi, Folks- I have a question regarding the "proper" use of try: finally:... Consider some code like this: d = Device.open() try: d.someMethodThatCanRaiseError(...) if SomeCondition: raise...
54
by: Stefan Arentz | last post by:
I was just reading through some old articles in the 'Why not develop new language' thread and came across the finally debate. Everytime I mention 'finally' to C++ programmers I get almost...
2
by: maxw_cc | last post by:
Hi to all of you, I was wondering what the Semantics part in C standard is really for? What should be on the constraints part and what should be on the semantics part? Is the implementation...
14
by: Dan Jacobson | last post by:
How is this for correct HTML 4.01 headers?: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="zh-tw"><head> <meta http-equiv="Content-Type"...
10
by: avasilev | last post by:
Hi all Its one of my little pragramming challenges to implement a try/finally construct in C++. I have done several implementations but they all have limitations. Have tried mostly using a...
35
by: dragoncoder | last post by:
Just a simple theoritical question to the experts. What was the rationale behind making STL containers follow copy semantics rather than reference semantics. References almost always make things...
2
by: =?Utf-8?B?QU1lcmNlcg==?= | last post by:
I would like to define a structure or a class with an array field that behaves like a simple value-semantics variable. For example, I want something like public structure polynomial public a()...
28
by: parag_paul | last post by:
http://concentratedlemonjuice.blogspot.com/2008/06/about-c-puzzles-on-my-blog.html I actually am searching for more work done on C now, today there are many sites that will provide you college...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.