On Thursday, 24 January 2013 at 17:21:38 UTC, Artur Skawina wrote:
On 01/24/13 17:52, ParticlePeter wrote:
Yes, but this can be broken by:

import core.stdc.stdio : printf;

struct Singleton  {

private :
        this( int a = 0 ) {} ;
        static Singleton * s ;

public :
        @disable this() ;
        static Singleton* instance()  {
                if ( s is null )
                        s = new Singleton(0) ;
                return s ;
        }

        int val = 0 ;
}

void main()
{
        Singleton s = * Singleton.instance;
        printf( "%d\n", s.val ) ; //
        Singleton.instance.val = 2 ;
        printf( "%d\n", s.val ) ; //0
}

Here s is explicitly defined to be a struct object, not pointer (reference), so main.s is independent of further modification of Singleton.instance.

O.k. good to know, I'll try to avoid this. But one thing is still not clear, This method here ( my first approach ) does return a reference to an object on the heap, right ?

static ref Singleton instance()  {
    if ( s is null )
        s = new Singleton( 0 ) ;
    return * s ;
}

so when I use it with:
auto another_s = Singleton.instance ;

Why is the s inside the struct and another_s not identical ?
Afaik that is the purpose of the ref keyword ?

There currently are no reference variables in D [1]; the only way to get a reference to something is via function arguments (including implicit method ones) and function returns. So assigning a ref-return means a copy.

You can workaround it like this:

struct Singleton  {
private:
    this( int a = 0 ) {} ;
    static Singleton* s ;

public:
    @disable this();
    @disable this(this);
    static instance() @property {
static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias obj this; @disable this(this); }
        if ( s is null )
            s = new Singleton( 0 ) ;
        return Ref!(typeof(this))(s) ;
    }

    int val = 0 ;
}

though, that's not how I'd do it.

artur

[1] Classes don't count; they are a reference /types/.

Well ... I think I as well would not wanna do it like this, thanks :-) I'm fine with returning and using a pointer, fortunately there is no difference in syntax as in c, so it doesn't matter.

Reply via email to