Singleton Pattern with struct

ParticlePeter ParticlePeter at gmx.de
Thu Jan 24 09:35:08 PST 2013


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.



More information about the Digitalmars-d-learn mailing list