Re: Virtual Destructor - Implication & Specification
On Apr 4, 4:49 am, "Maxim Yegorushkin" <maxim.yegorush...@gmail.com>
wrote:
On 2 Apr, 08:36, "Le Chaud Lapin" <jaibudu...@gmail.com> wrote:
A while back I originated a post about a Virtual_Destructor<> wrapper
template whose purpose was simply to add a no-op virtual destructor to
a class. Using it. at least under Microsoft Windows, circumvents the
new/delete heap mismatch problem.
If I understand correctly, the problem stems from allocating *memory*
from one heap and returning it to another. The natural way to solve it
would be to allocate and deallocate memory from the same translation
unit, would not it?
You understanding is correct, and that is one way that programmers in
Windows often go about solving this problem. For every object
manufactured inside the DLL using the new operator, there will be
another function inside the DLL whose sole purpose is to call delete
against a pointer to such object. Then, within the EXE, whenever the
programmer needs to invoke delete operation against a pointer to
object manufactured in DLL, he first binds to the special deallocation
function inside the DLL, then invokes it, supplying pointer to the
object.
Over the years I have had repeated arguments with colleagues who
emphatically insist that making the destructor of a class virtual
under Windows will *not* eliminate the heap mismatch problem, and each
time, I have to write an EXE and a companion DLL to prove that it
does.
While it may work, it does not seem to be an elegant solution. The
reason being that C++ distinguishes between allocating/deallocating
raw memory and initializing/deinitializing an object in that memory.
The destructor is a means of the latter, not the former. By trying to
affect deallocation using means of deinitialization relying on a
platform specific behavior rather than the standard, imho, only
obscures the problem.
Au contraire...not only is it an elegant solution, but it is the
solution implicitly recommended (to some degree) by Stroustrup
himself, if I am not mistaken. I had the same line of reasoning you
had until I read carefully read what Stroustrup was saying on pages
421/422 of TCPPPL 3rd Edition. I do not have my copy with me now, but
there is a place where he says, paraphrased, "In principle,
deallocation is done from within the destructor, which knows the
size..." I remember reading this sentence and thinking, "that's
weird..." technically, the tilde(~) function should not be used to
have anything to do with memory deallocation. It should be used for
deinitializing only. Then I noticed the "In principle..." part, and
thought carefully about that. Then I thought carefully about the
problem with invoking delete against pointers to polymorphic objects
and necessity of making the destructor virtual and getting the size
right. Then I thought about the fact that some derived objects might
have their own class-specific new/delete. Then I thought about how,
in several areas of the book, Stroustrup explicitly acknowledges the
existing of dynamically-linked libraries, and how they would be used
in C++.
After thinking about all of these things at once, it became clear what
was was happening, even before doing the disassembly of the code, and
it also became clear why Stroustrup began the sentence with "In
principle.." He did this, I believe, so as to say, "In practice, that
is very likely _not_ what any compiler writer would do." And of
course, he is right: I doubt any compiler writer would put the
equivalent of free() inside the destructor itself. Doing that would
eliminate the possibility of using the destructor as a functioned to
be called by a another, more broadly-scoped, outer destructor, among
other penalties. What Stroustrup was saying is that, in principle,
from the programmer's point of view, what happens will be left to the
destructor, in a deffered sense.
So, is the mechanism implementation dependent? Of course. If it is not
standard, then by definition it is. But I highly doubt that any other
compiler is doing anything different. Like many implementations of
language artifacts (e.g. using stacks for recursive calls), it would
not make sense to do it any other way.
-Le Chaud Lapin-
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]