On 2/27/2014 9:25 PM, Szymon Gatner wrote:


This is just an example but I would think that it is something rather
important to have... What about child objects un-registering themselves
in d-tors from a list that parent object holds and parent is destroyed
first? What about asynchronous completion handler object that should
notify some other object that it finished/not finished a job but a
notifee is already destroyed because application is being shut-down? I
honestly can't imagine how to reason about object graph lifetimes in GC
world and I am sure I am missing something very basic. Probably a very
different mindset.


Two simple rules I follow.

#1 Never rely on class destructors for determinstic clean up
#2 Never rely on class destructors for releasing system resources

I tend to add two methods to classes that need to do any sort of set up and clean up: initialize and terminate. Then, at app exit, I make sure that the terminate methods are called either with scope(exit) or, if I want to log any exceptions that percolate up to main, try-catch-finally. Something like this:

class TextureManager {
   private TexContainer _loadedTextures;
   public void initialize() {...}
   public void terminate() {
      foreach( tex; _loadedTextures[])
          tex.terminate();
   }
}

struct Game {
    @disable this();
    @disable this( this );

    private static TextureManager _texMan;

    public static void initialize() {
       _texMan = new TextureManager();
       _texMan.initialize();
    }
    public static void terminate() {
        _texMan.terminate();
    }
}

void main() {
   scope( exit ) Game.terminate();
   Game.initialize();
}

In some parts of a system, for objects that tend to be short lived, I'll use structs with destructors for RAII. A good example of this is for vertex and fragment shaders. The shader programs are long-lived, so those are classes, but I always destroy the shader objects as soon as any programs that need them are built. So those are perfect candidates for the struct-based RAII approach.

RAII is a convenient tool, but it's just that, a tool. One of the tradeoffs you have to make with D's GC is that you can't use RAII the same way you do in C++. You *can* use it with structs, but for classes you're going to have to put C++ out of your head.

Reply via email to