Subject | New API: Exceptions |
---|---|
Author | Jim Starkey |
Post date | 2000-06-01T20:52:29Z |
Claudio had raised the question of why pointers to SQLException
objects were thown (and caught) rather than the objects themselves.
The difference in the handler is:
catch (SQLException exception)
{
...
}
and
catch (SQLException *exception)
{
...
delete exception;
}
As he pointed the, a problem with throwing a pointer is that
somebody has to delete the throw object or suffer a memory leak
(more about this later).
Here is the answer: If we want to declare SQLException as an
abstract class (as opposed the specifying the implementation
as part of the API), we have to use the pointer form. The first
example above is not legal C++: An abstract class cannot be
instantiated.
We could define SQLException with an implementation to allow the
object (i.e. non-pointer) case, but not without problems. In
case 1 above, a copy constructor would be necessary to copy
an implementation specific subclass of SQLException to SQLException
itself, which more or less eliminates any added value an implementation
extension might provide. It would also make extensions of the API
difficult and dangerous.
I think there great merit in defining the API as pure interface --
no inherited code. I think the pointer form is the way to go.
Which brings us to the question exception object life time. We
could say that an implementation controls the object life (like
next what?). Or we bite the bullet and use the same general
mechanism as other user visible object -- addRef/release. See
next post.
Jim Starkey
objects were thown (and caught) rather than the objects themselves.
The difference in the handler is:
catch (SQLException exception)
{
...
}
and
catch (SQLException *exception)
{
...
delete exception;
}
As he pointed the, a problem with throwing a pointer is that
somebody has to delete the throw object or suffer a memory leak
(more about this later).
Here is the answer: If we want to declare SQLException as an
abstract class (as opposed the specifying the implementation
as part of the API), we have to use the pointer form. The first
example above is not legal C++: An abstract class cannot be
instantiated.
We could define SQLException with an implementation to allow the
object (i.e. non-pointer) case, but not without problems. In
case 1 above, a copy constructor would be necessary to copy
an implementation specific subclass of SQLException to SQLException
itself, which more or less eliminates any added value an implementation
extension might provide. It would also make extensions of the API
difficult and dangerous.
I think there great merit in defining the API as pure interface --
no inherited code. I think the pointer form is the way to go.
Which brings us to the question exception object life time. We
could say that an implementation controls the object life (like
next what?). Or we bite the bullet and use the same general
mechanism as other user visible object -- addRef/release. See
next post.
Jim Starkey