J
JKop
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(false) {}
~HKEYe()
{
if (to_be_closed)
{
RegCloseKey(hkey);
}
}
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_closed = true;
//... some stuff
RegCloseKey(hkey);
hkey.to_be_closed = 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_destructed;
AutoDestructive() : t(), to_be_auto_destructed(false) {}
template<class A> AutoDestructive(A a) : t(a), to_be_auto_destructed
(false) {}
template<class A> AutoDestructive(const A a) : t(a),
to_be_auto_destructed(false) {}
template<class A, class B> AutoDestructive(A a, B b) : t(a,b),
to_be_auto_destructed(false) {}
template<class A, class B, class C> AutoDestructive(A a, B b, C c) : t
(a,b,c), to_be_auto_destructed(false) {}
virtual ~AutoDestructive() = 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:
~AutoDestructive_HKEY()
{
if (to_be_auto_destructed) RegCloseKey(t);
}
};
int main()
{
AutoDestructive_HKEY hkey;
LONG error_code = RegOpenKeyEx(HKEY_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
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(false) {}
~HKEYe()
{
if (to_be_closed)
{
RegCloseKey(hkey);
}
}
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_closed = true;
//... some stuff
RegCloseKey(hkey);
hkey.to_be_closed = 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_destructed;
AutoDestructive() : t(), to_be_auto_destructed(false) {}
template<class A> AutoDestructive(A a) : t(a), to_be_auto_destructed
(false) {}
template<class A> AutoDestructive(const A a) : t(a),
to_be_auto_destructed(false) {}
template<class A, class B> AutoDestructive(A a, B b) : t(a,b),
to_be_auto_destructed(false) {}
template<class A, class B, class C> AutoDestructive(A a, B b, C c) : t
(a,b,c), to_be_auto_destructed(false) {}
virtual ~AutoDestructive() = 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:
~AutoDestructive_HKEY()
{
if (to_be_auto_destructed) RegCloseKey(t);
}
};
int main()
{
AutoDestructive_HKEY hkey;
LONG error_code = RegOpenKeyEx(HKEY_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