Object destruction versus finalization
Florian
santa at nortpole.org
Tue Nov 12 14:40:24 PST 2013
On Tuesday, 12 November 2013 at 20:29:13 UTC, Dicebot wrote:
> On Tuesday, 12 November 2013 at 20:15:02 UTC, Florian wrote:
>> I played around a little and figured out, that destructors in
>> D work quite similarily to destructors in C++. They are
>> invoked, after the members of the instance being destructed
>> have been destroyed themselfes (or at least have been brought
>> into an invalid state). Therefore, these members cannot be
>> accessed savely from inside the destructor.
>
> What made you think so? It must be other way around. Destructor
> is expected to release resources held by object, it is
> necessary that those resources are still valid at destructor
> call point. It would have been completely against the mode of
> operations of garbage collector.
Let me explain this by discussing the example below. I created
method stubs, which write single lines to the console, so it is
quite easy to follow the control flow.
The main method creates an instance of a type "Session", which
itself has a member of type "Connection". Let us assume, that I
want to properly shutdown the "Connection" instance by invoking
its methods, when the "Session" is torn down. The example below
prints the following output:
~Connection
~Session
segmentation fault
This means, the destructor of "Connection" is invoked *BEFORE*
the destructor of "Session" is called. This yields to an invalid
reference for the call of the shutdown() method, leading to the
segmentation fault. Of course, in a scenario as simple as that,
it would be possible to move the shutdown() sequence into the
destructor of the "Connection" class. However, doing so is not
desirable. Just picture, that we want to set some timeout
parameters or the like for the shutdown depending on the state of
the "Session". This would become really messy. And be assured, I
have a more complex scenario, where I definitely want to invoke
methods on memeber instances when an instance is destroyed. I am
convinced there is a reason for finalizing objects like Java, C#
and managed C++ do.
Example:
import std.stdio;
class Connection {
this() { }
void shutdown() { writeln("shutdown"); }
~this() { writeln("~Connection"); }
}
class Session {
Connection connection;
this() { connection = new Connection(); }
~this() {
writeln("~Session");
connection.shutdown(); // -> segmentation fault
}
}
void main() { auto session = new Session(); }
More information about the Digitalmars-d-learn
mailing list