Either you're making no sense, or there's something about C++
you haven't understood.
If you separate the object destruction phase from the memory
release phase,
You don't change much. Currently, operator delete() and the
destructor are two different functions. The only link in the
current situation is that operator delete() will not normally be
called unless the destructor is called, so in a lot of cases,
you end up with destructors you wouldn't otherwise need.
then you must be asserting that you are going to be explicitly
invoking the object destruction phase, at some point,
yourself, instead of relying on the garbage collector on doing
that.
Certainly. The garbage collector never invokes object
destruction. The two things are separate concepts, and as such
should be disassociated.
But if that's what you're going to do, if you are going to be
destroying your objects yourself, then what exactly are you
going to gain by not freeing the memory, right then and there,
instead of leaving it to the garbage collector to free the
memory at some later, indeterminate point?
A lot of objects don't have any real actions which have to be
carried out at the end of their lifetime. By design, in many
cases.
If we compare to Java, of course, garbage collection is much
less fundamental in C++. Our value objects are allocated on the
stack, and copied---since dynamic allocation isn't involved,
garbage collection is completely irrelevant. Entity objects
have a defined lifetime in both languages, and must be
explicitly disposed of (normally via the destructor in C++, and
some specific member function in Java)---the real problem with
them is ensuring that all interested parties are notified. In
such cases, garbage collection can help in debugging---you can
mark the object as invalid, and check the mark any time the
object is used, without any risk that the memory underlying the
object will be reused (and the mark overwritten) as long as
anyone still holds a pointer to the object. But it's purely a
defensive programming issue---in correct code, it shouldn't make
a difference. The fact remains, however, that there are other
types of objects. They're not numerous, but they do exist. In
my code, for example, I make some use of agents---small,
polymorphic objects without any real data (perhaps a pointer to
the object they operate on). Garbage collection is perfect for
them. And in other domains, there are complicated graph
structures---this is where garbage collection shines.
The usual way I've used garbage collection to date is to simply
replace operator new() with a function which calls gc_malloc(), and
operator delete() with one which calls gc_free(). And then
simply drop user defined destructors in classes like string, or
in my agents. It's less code which needs to be written. And
less code is always an improvement.
Bravo! You finally got it.
What do you mean, finally. This has always been a fundamental
concept for any competent programmer.
What you seem to be missing is the "if". In a lot of
applications, that if will usually be false, so the then part of
the sentence doesn't apply. Obviously, you need to do the
analysis to determine if it applies, but you need to do that
anyway, garbage collection or not---you need to know what to put
in the destructor before you write it. The difference when
using garbage collection is that if that analysis shows that
nothing really needs to be done (except memory management),
you're through. You've finished the job. Without garbage
collection, you've still got code to write.
In the contexts I've worked in, I've always had enough code to
write as is, without artificially creating the need to write
more.
If you're going to explicitly destroy the object, then you're
going to free the memory right than and there.
Maybe. You might want to keep it as long as there are pointers
to it, for error checking.
And of course, if you weren't going to explicitly destroy the
object, because disposing of the object had no significant
behavior, then garbage collection is a definite gain.
To stop short before doing that, and leaving it to the garbage
collector, is absolutely demented, and you gain absolutely
nothing from doing that.
You gain robustness, when you need to explicitly dispose of the
object, and a lot less code to write, when you don't.
If you're going to use a garbage collection model,
Garbage collection isn't a model. It's a tool. Maybe that's
where you're having problems with it.
it logically follows that you're postponing object
destruction/finalization until then. Because if you're not --
if you're going to destroy and finalize the object yourself --
then you'll simply free the memory at the same time too,
because by the virtue of invoking the destructor, you are
stating that no references to the object remain, so you can
free the memory right than and there.
Disposing of an object is logically distinct from memory
management. The only constraint is that the object must be
disposed of before the memory is reused. Disposing of an
object---by that I mean explicitly terminating its lifetime,
with observable behavior linked to the end of lifetime---is a
design issue, and must always be addressed, at the design level,
regardless of the tool set used at a lower level. Memory
management is a much lower level issue.
Refusing to do that, and instead choosing to foist a
completely unnecessary garbage collection framework on your
neck, in that situation, is completely and utterly retarded.
And that's precisely why I wrote, right from the start, that
garbage collection is only for those who are too stupid to
manage and keep track of their objects, and their lifetime,
themselves.
Which, of course, is false. No professional, today, would start
a new C++ application without considering garbage collection,
any more than he'd start it without considering templates, or
threads, or any other feature readily available. In many ways,
it's a lot like threads: you use it if it helps produce a
working application in less time, and you don't if it doesn't.
It costs nothing if you don't use it, and if it is appropriate,
using it reduces costs.
Because if they do have enough wits to keep track of their
objects' lifetime, and invoke their destructors at the
appropriate time, they'll just release the memory at the same
time. We even have an operator for doing that. It's called
"delete".
As another example in this thread has shown, it isn't always
that simple.