As far as I understand RAII refers to acquire resources in ctor and release them in dtor.
Ctor acquires some resources and can fail, resulting in an exception. Dtor releases the resources and can also fail, but exception from dtors are foobar so no exception.
class A {
A() throw(Ex) { // acquire resources }
~A() throw() { // release resources }
}
So if the user of class A should be made aware of an error happening in A′s uninitialisation I can outsource uninitialisation to a function that throws, called from a dtor that swallows exceptions:
class A {
A() throw(Ex) { // acquire resources }
~A() throw() { try {Release(); } catch(...) {} }
void Release() throw(Ex) { // release resources }
}
That way the user can call Exit() if he wants feedback for release-error or just ignore by letting dtor do it′s job when A goes out of scope (e.g. some other exception occurs where A is used).
To prevent multiple executions of Exit() (first explicitly from user, later indirect by dtor) I have to add an init-status:
class A {
bool init;
A() throw(Ex) { init = true; // acquire resources }
~A() throw() { try {Release(); } catch(...) {} }
void Release() throw(Ex) {
if(!init) return;
init = false;
// release resources
}
}
Are there better ways to do this or do I have to implement that pattern every time resource-release can fail and I want to know about it?
std::fstream
does this.noexcept
ornoexcept(true)
).