Ok, I have to add in an answer to the points you made in a separate answer post:
(It would be a lot more convenient if you'd edited this into the original question, so it doesn't end up at the bottom below the answers to it.
If all cleanup always gets done in
destructors then there wouldn't need
to be any cleanup code in a catch
block - yet C++ has catch blocks where
cleanup actions get done. Indeed it
has a block for catch(...) where it is
only possible to do cleanup actions
(well, certainly can't get at any
exception information to do any
logging).
catch has a completely separate purpose, and as a Java programmer you should be aware of that. The finally clause is for "unconditional" cleanup actions. No matter how the block is exited, this must be done. Catch is for conditional cleanup. If this type of exception is thrown, we need to perform a few extra actions.
The cleanup in a finally block will
get done whether there was an
exception thrown or not - which is
what one always wants to happen when
cleanup code does exist.
Really? If we want it to always happen for this type (say, we always want to close a database connection when we're done with it), then why don't we define it once? In the type itself? Make the database connection close itself, rather than having to put a try/finally around every single use of it?
That's the point in destructors. They guarantee that each type is able to take care of its own cleanup, every time it's used, without the caller having to think of it.
C++ developers from day one have been
plagued with having to repeat cleanup
actions that appear in catch blocks in
the code flow that occurs upon
successful exit from the try block.
Java and C# programmers just do it
once in the finally block.
No. C++ programmers have never been plagued by that. C programmers have. And C programmers who realized that c++ had classes, and then called themselves C++ programmers have.
I program in C++ and C# daily, and I feel I'm plagued by C#'s ridiculous insistence that I must supply a finally clause (or a using
block) EVERY SINGLE TIME I use a database connection or something else that must be cleaned up.
C++ lets me specify once and for all that "whenever we're done with this type, it should perform these actions". I don't risk forgetting to release memory. I don't risk forgetting to close file handles, sockets or database connections. Because my memory, my handles, sockets and db connections do it themselves.
How can it ever be preferable to have to write duplicate cleanup code every time you use a type? If you need to wrap the type because it doesn't have a destructor itself, you have two easy options:
- Look for a proper C++ library which provides this destructor (hint: Boost)
- Use boost::shared_ptr to wrap it, and supply it with a custom functor at runtime, specifying the cleanup to be done.
When you write application server
software like Java EE app servers
Glassfish, JBoss, etc., you want to be
able to catch and log exception
information - as opposed to let it
fall on the floor. Or worse fall into
the runtime and cause a ungraceful
abrupt exit of the application server.
That's why it's very desirable to have
an overarching base class for any
possible exception.
And C++ has just such a class. std::exception.
Have done C++ since the CFront days
and Java/C# most of this decade. Is
clear to see there's just an enormous
culture gap in how fundamentally
similar things are approached.
No, you've never done C++. You've done CFront, or C with classes. Not C++. There's a huge difference. Quit calling the answers lame, and you might learn something about the language you thought you knew. ;)