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/.