* James Kanze, on 29.11.2010 19:47:
Can you expound on that? I don't see how making the destructor
protected will make it accessible to a single for-all-types
destroy function.
C++ has a wonderful solution for that, James. It's called "friend". I suggest
reading about C++ "friend" in your textbook.
Instead of directly using "friend" in every such class, you can use another
wonderful language feature called "inheritance". This one's really cool! You can
"inherit" in all kinds of functionality, including destroy functionality.
I think you'll find that your textbook also covers the concept of "inheritance".
Generally, if the class is designed to be a base, I'd make the
destructor protected; otherwise, I'd make it private. But more
generally... any given class has specific semantics. And users
use the class in accordance with its semantics. If the
semantics require it to be dynamically allocated, I've yet to
encounter programmer who would attempt to allocate it on the
stack. It's one of those errors that are so rare, they aren't
worth bothering with.
If you're learning C++ coming from Python, say, then you're in for a little
shock! The philosophy in languages like Python is to provide other programmers
with as much access to things as possible, so that they can do whatever they
want. This was and is also the philosophy of the language called "C". But it
turned out that for larger programs it's Really Helpful to have the compiler
catch errors, instead of having to try to reproduce errors at run time. And in
order to enable the compiler to catch errors, C++ provides all kinds of means
for *restricting* what the programmer can do (that's the "++" in "C++"), telling
the compiler that if the programmer does that, or that, hey, diagnose that as an
error, please. It's a completely different philosophy.
It might seem strange at first, but consider the Unix idea of files as simply
streams of bytes. This *restriction* on what a file can be, enabled a lot of
useful functionality where different programs could be fitted together; they
could more easily work with each others' data.
So, somewhat paradoxically, good restrictions help both to catch errors
automatically, and help to enable functionality. Bad restrictions are, however,
bad -- some intelligence and thoughtfulness is required in order to choose the
good restrictions and don't choose the bad ones. C++ lets you enforce good
restrictions, but, thereby, it also lets you enforce bad ones: take care!
Cheers & hth.,
- Alf