A simple RAII wrapper for acquiring a Thingy that has two alternative
acquire methods, acquire() and acquireAndFurtle():
class ThingyAcquirer : private boost::noncopyable
{
public:
explicit ThingyAcquirer (Thingy& thingy, bool furtle = false) :
mThingy(thingy)
{
if(furtle)
mThingy.acquireAndFurtle();
else
mThingy.acquire();
}
~ThingyAcquirer ()
{
mThingy.release();
}
private:
mThingy;
};
When creating objects like this, I (scarily frequently) find myself
typing the wrong thing. Instead of
ThingyAcquirer acquirer(someThingy);
I find my fingers typing:
ThingyAcquirer(someThingy);
This is OK because it causes a compiler error - the compiler parses it
as declaring an object called someThingy, which already exists with a
different type.
However, with the extra parameter this becomes legal C++:
ThingyAcquirer(someThingy, true);
, which compiles happily and releases the thingy immediately!
I've been caught out by this a few times, though so far only ever with
one parameter. If it ever happens with a 2-parameter constructor (such
as those on a couple of boost::thread's RAII locker classes), I'll
probably have a nasty bug on my hands.
Maybe it's just me, but I find this a really easy mistake to make. One
reason is that RAII wrappers often represent something that is
intuitively an action (acquiring a resource), which something stupid in
my subconscious interprets as a function call. Another reason is that I
am not going to be refering to this thing again (not much point - its
only public members are the constructor and destructor), so it's easy
to forget to give it a name.
It seems to me that creating a temporary RAII object is something you
would never, ever want to do, but I can't think of any way to modify
ThingyAcquirer that would make the above code illegal. Can anyone else? 6 1829
Heh,
s/mThingy/Thingy& mThingy/
Guess I ought to check things actually compile before posting them,
sorry...
tomthemig...@googlemail.com wrote:
A simple RAII wrapper for acquiring a Thingy that has two alternative
acquire methods, acquire() and acquireAndFurtle():
class ThingyAcquirer : private boost::noncopyable
{
public:
explicit ThingyAcquirer (Thingy& thingy, bool furtle = false) :
mThingy(thingy)
{
if(furtle)
mThingy.acquireAndFurtle();
else
mThingy.acquire();
}
~ThingyAcquirer ()
{
mThingy.release();
}
private:
mThingy;
};
When creating objects like this, I (scarily frequently) find myself
typing the wrong thing. Instead of
ThingyAcquirer acquirer(someThingy);
I find my fingers typing:
ThingyAcquirer(someThingy);
This is OK because it causes a compiler error - the compiler parses it
as declaring an object called someThingy, which already exists with a
different type.
However, with the extra parameter this becomes legal C++:
ThingyAcquirer(someThingy, true);
, which compiles happily and releases the thingy immediately!
I've been caught out by this a few times, though so far only ever with
one parameter. If it ever happens with a 2-parameter constructor (such
as those on a couple of boost::thread's RAII locker classes), I'll
probably have a nasty bug on my hands.
Maybe it's just me, but I find this a really easy mistake to make. One
reason is that RAII wrappers often represent something that is
intuitively an action (acquiring a resource), which something stupid in
my subconscious interprets as a function call. Another reason is that I
am not going to be refering to this thing again (not much point - its
only public members are the constructor and destructor), so it's easy
to forget to give it a name.
It seems to me that creating a temporary RAII object is something you
would never, ever want to do, but I can't think of any way to modify
ThingyAcquirer that would make the above code illegal. Can anyone else?
On 10 Oct 2006 04:53:53 -0700, to**********@googlemail.com wrote:
>A simple RAII wrapper for acquiring a Thingy
....
>When creating objects like this, I (scarily frequently) find myself typing the wrong thing. Instead of
ThingyAcquirer acquirer(someThingy); I find my fingers typing:
ThingyAcquirer(someThingy);
This is OK because it causes a compiler error - the compiler parses it as declaring an object called someThingy, which already exists with a different type.
Hmm, really?
>However, with the extra parameter this becomes legal C++:
ThingyAcquirer(someThingy, true); , which compiles happily and releases the thingy immediately!
I've been caught out by this a few times, though so far only ever with one parameter. If it ever happens with a 2-parameter constructor (such as those on a couple of boost::thread's RAII locker classes), I'll probably have a nasty bug on my hands.
Maybe it's just me, but I find this a really easy mistake to make. One reason is that RAII wrappers often represent something that is intuitively an action (acquiring a resource), which something stupid in my subconscious interprets as a function call. Another reason is that I am not going to be refering to this thing again (not much point - its only public members are the constructor and destructor), so it's easy to forget to give it a name.
It seems to me that creating a temporary RAII object is something you would never, ever want to do, but I can't think of any way to modify ThingyAcquirer that would make the above code illegal. Can anyone else?
Declare a free function:
void ThingyAcquirer (Thingy& thingy, bool furtle = false);
and never define it. Should give a liker error.
Best wishes,
Roland Pibinger to**********@googlemail.com wrote:
A simple RAII wrapper for acquiring a Thingy that has two alternative
acquire methods, acquire() and acquireAndFurtle():
class ThingyAcquirer : private boost::noncopyable
{
public:
explicit ThingyAcquirer (Thingy& thingy, bool furtle = false) :
mThingy(thingy)
{
if(furtle)
mThingy.acquireAndFurtle();
else
mThingy.acquire();
}
~ThingyAcquirer ()
{
mThingy.release();
}
private:
mThingy;
};
I suggest to not do that, better something like this:
class ThingyAcquirerBase
{
protected:
ThingyAcquirerBase (Thingy & thingy) :
mThingy (tingy)
{ }
~ThingyAcquirer ()
{
mThingy.release();
}
void acquire ()
{
mThingy.acquire ();
}
void acquireAndFurtle ()
{
mThingy.acquireAndFurtle ();
}
private:
mThingy;
};
class ThingyAcquirer
{
public:
explicit ThingyAcquirer (Thingy & thingy) :
ThingyAcquirerBase (tingy)
{
acquire ();
}
};
class ThingyAcquirerFurtler
{
public:
explicit ThingyAcquirerFurtler (Thingy & thingy) :
ThingyAcquirerBase (tingy)
{
acquireAndFurtle ();
}
};
--
Salu2
....
This is OK because it causes a compiler error - the compiler parses it
as declaring an object called someThingy, which already exists with a
different type.
Hmm, really?
Indeed. It came as a surprise to me. The relevant part of the standard
is 6.8 - Ambiguity Resolution.
Declare a free function:
void ThingyAcquirer (Thingy& thingy, bool furtle = false);
and never define it. Should give a liker error.
Nice idea. The downside is that in order to use it the ThingyAcquirer
you'll have to use an elaborated type specifier (9.1 para 2):
class ThingyAcquirer acquirer(someThingy, true);
I think this is a small price to pay for avoiding this pitfall
(pratfall?). Where there are 3rd party RAII classes, like the boost
ones, I could have a #ifdef that declares these functions for a
make-sure-I-haven't-made-that-stupid-mistake-with-the-RAII-objects
build. Cool.
Thanks for your help.
Tom
That would be much better here. Unfortunately it isn't possible if the
RAII class is third-party, or if the underlying acquire() method takes
two or more parameters.
Thanks for your help.
Tom
On 10 Oct 2006 11:50:48 -0700, to**********@googlemail.com wrote:
>Declare a free function:
void ThingyAcquirer (Thingy& thingy, bool furtle = false);
and never define it. Should give a liker error.
Nice idea. The downside is that in order to use it the ThingyAcquirer you'll have to use an elaborated type specifier (9.1 para 2):
class ThingyAcquirer acquirer(someThingy, true);
Actually, that's not really elegant. It's unfortunate that the type
specifier is needed even though the use is not ambigous. Maybe you
should write a macro that creates the object for you??
Best wishes,
Roland Pibinger This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: codymanix |
last post by:
Last night I had several thought about RAII and want to discuss a bit.
Why doesn't CSharp support destructors in structs? Wouldn't that make RAII
possible like in C++? When the struct goes out of...
|
by: Markus Elfring |
last post by:
The class "auto_ptr" implements the RAII pattern for pointer types. It
seems that an implementation is not provided for non-pointer values by
the STL so far.
I imagine to use the "acquisition" for...
|
by: alanstew |
last post by:
With the body tag calling out 'window onload', a function with a
'window.open' fails at the 'window.open' line. If I cut out the body
tag, the function executes as normal.
At first I thought it...
|
by: chettiar |
last post by:
Hi,
I am dropping an index and recreating it to lower the high water mark.
The index creation is taking a lot of time. I am stuck as to why it
does so. Is there any way that I can find out why...
|
by: plahey |
last post by:
I have been dabbling in Python for a while now. One of the things that
really appeals to me is that I can seem to be able to use C++-style
RAII idioms to deal with resource management issues.
...
|
by: JohnQ |
last post by:
Scenario: A GUI program is developed such that the startup sequence is
controlled by the instantiation of a key object which instantiates other
objects etc. until it finally arrives at the point...
|
by: Rahul |
last post by:
Hi Everyone,
class Base
{
public : Base(int i)
{
printf("constructor\n");
}
void disp()
{
|
by: DolphinDB |
last post by:
Tired of spending countless mintues downsampling your data? Look no further!
In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: Vimpel783 |
last post by:
Hello!
Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
|
by: PapaRatzi |
last post by:
Hello,
I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
|
by: Defcon1945 |
last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
|
by: Shællîpôpï 09 |
last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
| |