On Fri, 01 Feb 2013 02:07:00 -0500, monarch_dodra <monarchdo...@gmail.com>
wrote:
On Thursday, 31 January 2013 at 23:53:26 UTC, Steven Schveighoffer wrote:
A destructor should ONLY be used to free up resources other than GC
allocated memory. Because of that, it's generally not used.
It should be used almost as a "last resort".
For example, a class that holds a file descriptor should have both a
destructor (which closes the descriptor) and a manual close method.
The former is to clean up the file descriptor in case nobody thought to
close it manually before all references were gone, and the latter is
because file descriptors are not really managed by the GC, and so
should be cleaned up when they are no longer used.
This kind of gives us a paradox, since the class is managed via the GC,
how do you know it's no longer used (that is, how do you know this is
the last reference to it)? That is really up to the application
design. But I wouldn't recommend relying on the GC to clean up your
descriptors.
-Steve
I've actually run into this very issue: I was iterating on files,
opening them, and placing the descriptor in GC-allocated RAII data. I
can't remember if class or struct, but not a big issue. Come to think
about it, I think I was using "File", but allocating them because I
thought they were classes `auto f = new File("my file", "r")`.
After running for a second, my program halts, because an exception was
thrown trying to open a new file:
"Cannot open file: Too many open file handles".
It was basically: Sure, the GC will destroy and close files for you...
if you forget... eventually...
I ended up closing them in scope(exit) blocks. Problem immediately
solved. Or I could have stopped allocating my File's on the heap.
Either way, it shows you shouldn't rely on the GC for deterministic
destruction.
Actually, that's a different problem. File is a struct, and structs do
NOT have their destructor run by the GC. Only Objects do.
This is a GC limitation, since structs do not contain a pointer to their
typeinfo like classes do, and there is no provision for storing a pointer
to the typeinfo of a block. It could be fixed by a more precise GC.
AIUI, we have something like that coming, but I've been hearing that for
more than a year ;)
-Steve