|
Boost Testing : |
From: Robert Ramey (ramey_at_[hidden])
Date: 2005-10-19 15:11:13
Jim Douglas wrote:
Here is the program:
class A {
virtual f() = 0;
protected:
~A(); // note::destructor NOT virtual
};
class B : public A
{
public:
~B();
virtual f();
};
main() {
A *MyPtr;
MyPtr = new B; // this is perfectly legal and very useful
delete MyPtr; // only calls the dtor for A
// nope: fails to compile with syntax error here
}
It fails to compile at the point where an error would otherwise occur.
> In the above example the delete would only clean up the base class A
> and leave bits of the derived class B lying around in memory causing a
> memory leak. If you make A's dtor virtual then it will clean up B
> correctly.
Nope: It will still fail to compile - exactly as I intended.
>> The idea is to require calling of the derived base class rather and
>> trap attempts
>> to violate this constraint.
>
> But that's exactly what happens with a virtual dtor. The derived class
> dtor is called automatically. You _cannot_ get it wrong.
nope: In the real situation I have things are a little bit more problematic
class A {
...
};
// B is defined in a DLL
class B {
};
If the code for B has been explicitly unloaded, the Vtable of a has an
invalid pointer
and the program fails. This is why I wanted to explicitly forbid calling
the destructor
through the base class - which I have been able to do.
I realize that this isn't customery and maybe is worth a warning - but I
should be able to
turn the warning off.
> (Please don't take this the wrong way)
Don't worry, I'm used to it.
> Because your code in its present form violates every C++ coding standard
> ever written.
Hmmm - that's a pretty sweeping statement. I havn't seen issues addressed
by
dynamic loading and unloading of code even addressed by any of the
references you mention.
For that matter I don't know if the are even addressd by the C++ standard.
Nevertheless, this is currently being done by some users of the
serialization library and the
failure to forsee it created some bugs. In the course of fixing these
bugs - (very hard to
track down) virtual was removed from the derived class destructors and the
above was
used to trap this behavior at compile time.
Though it might not seem apparent, I am aware of the rationale described by
the authors
you mention. I don't know that they have considered cases like this. I
believe that the idiom
represented above will produce the same benefit (assuring that the most
derived destructor
is being called in a way that is more effective in this context.
> That's why the warning is hard-coded into the GNU compiler.
Hmmm - maybe that's why its only a warning or maybe that's why its the only
compiler
that makes this complaint.
Robert Ramey