GC: finalization order?!

Martin Kinkelin noone at spam.com
Sun Feb 20 04:15:06 PST 2011


I came to the same conclusion. Even if Parent is a struct, it may get
destructed after its Child (e.g., in case the Parent struct is a field
of another class).
What I did is to use a custom allocator for Child, so that Child
instances are not managed by the GC:

----------
import std.stdio;
import std.c.stdlib;
import core.exception;

private class Child
{
    new(size_t size)
    {
        writeln("Child.new()");
        void* p = malloc(size);
        if (!p)
            onOutOfMemoryError();
        return p;
    }
    delete(void* p)
    {
        writeln("Child.delete()");
        if (p)
            free(p);
    }


    private size_t _refs;

    this()
    {
        writeln("Child.__ctor()");
        _refs = 1;
    }
    ~this()
    {
        writeln("Child.__dtor()");
        if (_refs != 0)
            throw new Exception("still referenced");
    }

    void addRef() { _refs++; }
    void release()
    {
        if (--_refs == 0)
            delete this;
    }
}

class Parent
{
    private Child _child;

    this()
    {
        writeln("Parent.__ctor()");
        _child = new Child();
    }
    ~this()
    {
        writeln("Parent.__dtor()");
        if (_child)
            _child.release();
    }
}

unittest
{
    auto p = new Parent();
}
----------

Output:
----------
Parent.__ctor()
Child.new()
Child.__ctor()
Parent.__dtor()
Child.__dtor()
Child.delete()
----------

This way, Child is destructed as soon as the last related Parent is destructed.
Thanks for clarifying!


More information about the Digitalmars-d-learn mailing list