-
Key: CPP12-37
-
Legacy Issue Number: 4210
-
Status: closed
-
Source: University of California, Irvine ( Carlos O'Ryan)
-
Summary:
formal/99-07-41 in section 1.36.3 includes the following code:
---------------- cut here ----------------
class ServantBase_var {
public:~ServantBase_var ()
{ if (_ptr != 0) _ptr->_remove_ref (); }
ServantBase_var& operator=(ServantBase* p)
{ if (_ptr != 0) _ptr->_remove_ref (); _ptr = p; return *this; }
ServantBase*& out()
{ if (_ptr != 0) _ptr->_remove_ref (); _ptr = 0; return _ptr; }
};
---------------- cut here ----------------
unfortunately this code is not exception safe: if
_remove_ref() throws the class is left in an inconsistent state (for
out() and operator=). The fact that the destructor can potentially
throw exceptions makes it extremely hard for application developers to
write exception safe classes.
A better implementation could be:
---------------- cut here ----------------
class ServanBase_var
{
ServantBase_var& operator=(ServantBase* p)
{ if (p == _ptr) return *this; ServanBase_var tmp (p); std::swap (p._ptr, p); return *this; }
ServantBase*& out()
{ if (_ptr != 0) _ptr->_remove_ref (); _ptr = 0; return _ptr; }
};
---------------- cut here ----------------
The implementation above also prevents silly mistakes like:
ServantBase_var foo = ...;
foo = foo.in ();
The destructor is a little trickier:
---------------- cut here ----------------
ServantBase_var::~ServantBase_var ()
{
// do not propagate exceptions out of the destructor
try { if (_ptr != 0) _ptr->_remove_ref (); }catch (...)
{
}
}
---------------- cut here ----------------Event better would be to add some throw spec to _remove_ref()
and _add_ref(). The spec is, as far as I can tell, silent in this
respect, thus those operations can throw anything. This is
unfortunate because it makes it harder to write exception-safe code,
both for application developers and ORB implementors alike. -
Reported: CPP 1.1 — Tue, 20 Feb 2001 05:00 GMT
-
Disposition: Resolved — CPP 1.2
-
Disposition Summary:
see below
-
Updated: Fri, 6 Mar 2015 21:38 GMT