Singleton Pattern with struct
Artur Skawina
art.08.09 at gmail.com
Thu Jan 24 09:14:20 PST 2013
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/.
More information about the Digitalmars-d-learn
mailing list