473,804 Members | 3,228 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Auto destruct


Using MSWindows as an example:

On MSWindows, there's a thing called the System Registry, which is a really
big database that holds all the settings of the OS. There's API's for
working with the registry. The two I will be concerned with are:

RegOpenKeyEx
RegCloseKey

Now, here's some code:

int main()
{
HKEY hkey;

RegOpenKeyEx( &hkey );

... //some stuff

RegCloseKey( hkey );
}
The only problem here is that if an exception is thrown during "some stuff",
then the key never gets closed. Here was my first solution:

class HKEYe
{
public:

HKEY hkey;
bool to_be_closed;

HKEYe() : to_be_closed(fa lse) {}

~HKEYe()
{
if (to_be_closed)
{
RegCloseKey(hke y);
}
}

operator HKEY&() { return hkey; }
operator const HKEY&() const { return hkey; }
HKEY* operator&() { return &hkey; }
const HKEY* operator&() const { return &hkey; }
};

int main()
{
HKEYe hkey;

RegOpenKeyEx( &hkey );

hkey.to_be_clos ed = true;

//... some stuff

RegCloseKey(hke y);
hkey.to_be_clos ed = false;

}
Now if an exception is thrown, then the key does get closed.

Anyway, my next thought was to make a template out of this. Has this been
done before? Anyway, here's my first attempt:
template<class T>
class AutoDestructive
{
public:

T t;
bool to_be_auto_dest ructed;

AutoDestructive () : t(), to_be_auto_dest ructed(false) {}
template<class A> AutoDestructive (A a) : t(a), to_be_auto_dest ructed
(false) {}
template<class A> AutoDestructive (const A a) : t(a),
to_be_auto_dest ructed(false) {}
template<class A, class B> AutoDestructive (A a, B b) : t(a,b),
to_be_auto_dest ructed(false) {}
template<class A, class B, class C> AutoDestructive (A a, B b, C c) : t
(a,b,c), to_be_auto_dest ructed(false) {}

virtual ~AutoDestructiv e() = 0;

operator T&() { return t; }
operator const T&() const { return t; }
T* operator&() { return &t; }
const T* operator&() const { return &t; }
};

class AutoDestructive _HKEY : public AutoDestructive <HKEY>
{
public:

~AutoDestructiv e_HKEY()
{
if (to_be_auto_des tructed) RegCloseKey(t);
}
};

int main()
{
AutoDestructive _HKEY hkey;

LONG error_code = RegOpenKeyEx(HK EY_CLASSES_ROOT ,
"*",
0,
KEY_QUERY_VALUE |KEY_SET_VALUE,
&hkey);

if (error_code == ERROR_SUCCESS)
{
hkey.to_be_auto _destructed = true;
}
}
Comments, questions, suggestions welcomed.

-JKop
Jul 22 '05 #1
25 3009
* JKop:

Now if an exception is thrown, then the key does get closed.

Anyway, my next thought was to make a template out of this. Has this been
done before?


Petri Marginean's ScopeGuard-class.

See the article about ScopeGuard (Andrei Alexandrescu & Petri Marginean) at
<url: http://www.cuj.com/documents/s=8000/cujcexp1812alex andr/>, source code
at <url: ftp://ftp.cuj.com/pub/2000/cujdec2000.zip> .

Note that for MSVC you'll have to replace use of standard __LINE__ with
Microsoft __COUNTER__ to make it work in general, at least if you're using the
"edit & continue" option of that compiler (it's a bit broken).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #2
> ...
Comments, questions, suggestions welcomed.


I prefer writing such a class like this:

class CRegKey {
public:
HKEY hkey;
CRegKey() {
if (RegOpenKeyEx( &hkey ))
throw...
}
~CRegKey() {
RegCloseKey( hkey );
}
};

int main()
{
{
CRegKey regKey;
...
}
};

The code for the class is so small that it is not worth making a template
for it. An invariant for the class is that the handle is open, so you do not
have to test if it is open, you do not have to remember to open it and you
do not have to remember to close it. As long as it is in scope it is open.

Niels Dybdahl
Jul 22 '05 #3
JKop wrote:
Using MSWindows as an example:

On MSWindows, there's a thing called the System Registry, which is a really
big database that holds all the settings of the OS. There's API's for
working with the registry. The two I will be concerned with are:

RegOpenKeyEx
RegCloseKey

Now, here's some code:

int main()
{
HKEY hkey;

RegOpenKeyEx( &hkey );

... //some stuff

RegCloseKey( hkey );
}
The only problem here is that if an exception is thrown during "some stuff",
then the key never gets closed. Here was my first solution:

class HKEYe
{
public:

HKEY hkey;
bool to_be_closed;

HKEYe() : to_be_closed(fa lse) {}

~HKEYe()
{
if (to_be_closed)
{
RegCloseKey(hke y);
}
}

operator HKEY&() { return hkey; }
operator const HKEY&() const { return hkey; }
HKEY* operator&() { return &hkey; }
const HKEY* operator&() const { return &hkey; }
};

int main()
{
HKEYe hkey;

RegOpenKeyEx( &hkey );

hkey.to_be_clos ed = true;

//... some stuff

RegCloseKey(hke y);
hkey.to_be_clos ed = false;

}
Now if an exception is thrown, then the key does get closed.

Anyway, my next thought was to make a template out of this. Has this been
done before? Anyway, here's my first attempt:
template<class T>
class AutoDestructive
{
public:

T t;
bool to_be_auto_dest ructed;

AutoDestructive () : t(), to_be_auto_dest ructed(false) {}
template<class A> AutoDestructive (A a) : t(a), to_be_auto_dest ructed
(false) {}
template<class A> AutoDestructive (const A a) : t(a),
to_be_auto_dest ructed(false) {}
template<class A, class B> AutoDestructive (A a, B b) : t(a,b),
to_be_auto_dest ructed(false) {}
template<class A, class B, class C> AutoDestructive (A a, B b, C c) : t
(a,b,c), to_be_auto_dest ructed(false) {}

virtual ~AutoDestructiv e() = 0;

operator T&() { return t; }
operator const T&() const { return t; }
T* operator&() { return &t; }
const T* operator&() const { return &t; }
};

class AutoDestructive _HKEY : public AutoDestructive <HKEY>
{
public:

~AutoDestructiv e_HKEY()
{
if (to_be_auto_des tructed) RegCloseKey(t);
}
};

int main()
{
AutoDestructive _HKEY hkey;

LONG error_code = RegOpenKeyEx(HK EY_CLASSES_ROOT ,
"*",
0,
KEY_QUERY_VALUE |KEY_SET_VALUE,
&hkey);

if (error_code == ERROR_SUCCESS)
{
hkey.to_be_auto _destructed = true;
}
}
Comments, questions, suggestions welcomed.


Congratulations , you just "invented" the RAII idiom. The std::auto_ptr
class in standard library is example of the RAII idiom. This idiom is
described in the book "The C++ Programming Language" from Bjarne
Stroustrup. Using the destructor to do proper clean up is a well known
C++ way to write exception safe code.

This idiom can be used for many more cases than just releasing memory or
handles. For example in a GUI application you could write a class that
in the constructor changes the cursor shape to an hourglass and in the
destructor restores the cursor to its previous shape.

void HeavyProcessing ()
{
WaitCursor wc;

// Do some stuff here....
// Exceptions or returns anywhere in the
// function will restore the cursor shape.
}

--
Peter van Merkerk
peter.van.merke rk(at)dse.nl
Jul 22 '05 #4
On Thu, 05 Aug 2004 13:49:32 GMT, JKop <NU**@NULL.NULL > wrote:

[...]
Now if an exception is thrown, then the key does get closed.

Anyway, my next thought was to make a template out of this. Has this been
done before?


Yes. For registry keys, you have CRegKey in ATL 7.x. A more generic
solution can be found in the ScopeGuard class, as mentioned by Alf. You
can also take a look at the SmartAny library in the PowerTools package
at:

http://www.gotdotnet.com/team/cplusplus/

--
Be seeing you.
Jul 22 '05 #5
Alf P. Steinbach posted:
* JKop:

Now if an exception is thrown, then the key does get closed.
Anyway, my next thought was to make a template out of this. Has this been done before?
Petri Marginean's ScopeGuard-class.

See the article about ScopeGuard (Andrei Alexandrescu &

Petri Marginean) at
<url: http://www.cuj.com/documents/s= 8000/cujcexp1812alex andr/>, sourcecode
at <url: ftp://ftp.cuj.com/pub/2000/cujdec2000.zip> .

Note that for MSVC you'll have to replace use of standard __LINE__ with Microsoft __COUNTER__ to make it work in general, at least if you're using the "edit & continue" option of that compiler (it's a bit broken).


Seems to me that the only problem is that you can't
specify arguments to the function. I suppose an inline
function with global references/pointers would do the job,
but how and ever.
I might keep going with my template and see how it goes.

First thing though, is there any way for a derived class
to inherit the constructors of its base? eg.

class Base
{
public:

Base() {}
Base(int) {}
Base(double&) {}
};

class Derived : public Base
{

};

int main()
{
double k;

Derived monkey(k);
}
I know that you can do the following:

class Derived : public Base
{
public:

Derived() : Base() {}
Derived(int) : Base(int) {}
Derived(double& ) : Base(double&) {}
};

But this will be very tedious if there's dozens of
contructors in the base. For example, for my template
class, the base will have loads of constructors so that
you can actually use the constructor of the type you're
"protecting ".
-JKop
Jul 22 '05 #6
g++ cnt.cpp -ansi -pedantic -o c.exe

C:\WINDOWS\TEMP/ccgrbaaa.o(.tex t$_ZN15AutoDest ructiveIiED2Ev+ 0x16):cnt.cpp:
undefined reference to `AutoDestructiv e<int>::CleanUp ()'
Can some-one else please try compile it and see what happens.

Anyone know what's wrong with the code?
Here's the code:
typedef int HKEY;
const int ERROR_SUCCESS(5 );

void RegCloseKey(HKE Y hkey) {}
int RegOpenKeyEx(HK EY *hkey) { return ERROR_SUCCESS; }

template<class T>
class AutoDestructive
{
public:

T t;
bool to_be_auto_dest ructed;

AutoDestructive () : t(), to_be_auto_dest ructed(false) {}

virtual void CleanUp() = 0;

~AutoDestructiv e()
{
this->CleanUp();
}

operator T&() { return t; }
operator const T&() const { return t; }
T* operator&() { return &t; }
const T* operator&() const { return &t; }
};
class AutoDestructive _HKEY : public AutoDestructive <HKEY>
{
public:

virtual void CleanUp()
{
if (to_be_auto_des tructed)
{
RegCloseKey(t);
to_be_auto_dest ructed = false;
}
}
};
int main()
{
AutoDestructive _HKEY hkey;

int error_code = RegOpenKeyEx(&h key);

if (error_code == ERROR_SUCCESS)
{
hkey.to_be_auto _destructed = true;
}
}
-JKop
Jul 22 '05 #7
JKop wrote:
Using MSWindows as an example:

On MSWindows, there's a thing called the System Registry, which is a really
big database that holds all the settings of the OS. There's API's for
working with the registry. The two I will be concerned with are:

RegOpenKeyEx
RegCloseKey

Now, here's some code:

int main()
{
HKEY hkey;

RegOpenKeyEx( &hkey );

... //some stuff

RegCloseKey( hkey );
}
The only problem here is that if an exception is thrown during "some stuff",
then the key never gets closed. Here was my first solution:

class HKEYe
{
public:

HKEY hkey;
bool to_be_closed;

HKEYe() : to_be_closed(fa lse) {}

~HKEYe()
{
if (to_be_closed)
{
RegCloseKey(hke y);
}
}

operator HKEY&() { return hkey; }
operator const HKEY&() const { return hkey; }
HKEY* operator&() { return &hkey; }
const HKEY* operator&() const { return &hkey; }
};

int main()
{
HKEYe hkey;

RegOpenKeyEx( &hkey );

hkey.to_be_clos ed = true;

//... some stuff

RegCloseKey(hke y);
hkey.to_be_clos ed = false;

}
Now if an exception is thrown, then the key does get closed.


System specific stuff but a generic issue. :-) Check "Resource
Acquisition is Initialisation" technique (RAII in short) even in my
messages of the past. :-)


Regards,

Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #8
* JKop:

Seems to me that the only problem is that you can't
specify arguments to the function.


You can.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #9
> ~AutoDestructiv e()
{
this->CleanUp();
}


The probem is with the above.

The following doesn't compile either:

class Base
{
public:

virtual void Monkey() = 0;

~Base()
{
this->Monkey();
}
};

class Derived : public Base
{
public:

virtual void Monkey()
{

}
};

int main()
{
Derived checker;
}
WHY?
-JKop
Jul 22 '05 #10

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

Similar topics

2
2609
by: Manlio Perillo | last post by:
Hi. This post follows "does python have useless destructors". I'm not an expert, so I hope what I will write is meaningfull and clear. Actually in Python there is no possibility to write code that follows C++ RAII pattern. Of course Python objects are not statics like in C++, but in C++ the auto_ptr class is used for enforcing this pattern for dynamical
6
4656
by: Lasse Skyum | last post by:
I'm currently learning STL and I hate not knowing what is gooing on "inside" STL... not because I really _need_ to know it to develop my game project, but that's just my nature... like most of you at this grounp I suspect. So the question is: How does a std::vector construct and destruct the elements in it? I know it has something to do with an allocator... Suppose I wrote:
1
13964
by: Glabbeek | last post by:
I'm changing the layout of my site. Instead of using tables, I will use DIVs. It's working fine, except for 1 thing: In IE6 some DIVs are not the correct width. Mozilla and Opera are showing the page the way I want. Does anybody know a solution for this? First of all, the code I am using: CSS ------- body {
21
4734
by: Steve | last post by:
Does anyone have any ideas on how to write self-destruct code? I need to run a one-time procedure the next time a database opens. If the procedure is successful, the procedure needs to be deleted and the code that initiated the procedure needs to delete itself. Thanks for any suggestions! Steve
20
2883
by: Vijay Kumar R. Zanvar | last post by:
Hello, Unlike register, auto keyword can not be used to declare formal parameter(s). Is there any specific reason for this? Kind regards, Vijay Kumar R. Zanvar
6
5075
by: Alpha | last post by:
I retrieve a table with only 2 columns. One is a auto-generated primary key column and the 2nd is a string. When I add a new row to the dataset to be updated back to the database. What should I do with the 1st column ? (Below I have a "1" in place for now). Also, Does the datase.AcceptChanges(); updates the changes to the database? Which command do I use to update the changes in dataset back to the Access database table? Thanks, Alpha...
5
5051
by: Samuel | last post by:
Hi, I am running into a problem of mixing UICulture = auto and allowing users to select culture using a dropdown list. I am detecting a querystring, "setlang", and when found, setting the CurrentUICulture to what's specified in the querystring. Since I want to allow UICulture auto detecting, I add UICulture = "auto" to page directive on each page.
5
3283
by: maya | last post by:
at work they decided to center divs thus: body {text-align:center} #content {width: 612px; text-align:left; margin: 0 auto 0 auto; } this works fine in IE & FF, EXCEPT in FF it doesn't work if I change 'auto' to 0 for left and right margin values; I have to leave those at 'auto'.. so I would like to know what exactly means 'auto' -- what value it represents exactly (and does it apply for all elements/values you might apply 'auto' to?)
5
3351
by: Frederick Gotham | last post by:
If we have a simple class such as follows: #include <string> struct MyStruct { std::string member; MyStruct(unsigned const i) {
21
6366
by: JOYCE | last post by:
Look the subject,that's my problem! I hope someone can help me, thanks
0
9708
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9588
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
10327
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10085
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9161
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6857
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5527
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3828
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2999
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.