Singleton & Constructor with paramethers

2004-06-11
2013-04-08
  • Francesco Vitale

    Hi!
    I noticed that Singleton can only be used with classes having a constructor with no paramethers.
    I succeeded in solving this limitation using the same approach I read on the Alexandrescu's Janitor class.

    I just modified the version I need: the version for VC6.0 :(
    By the way: I think it can be usefull so I explain the steps I followed.

    1-I moved both the SingletonHolder::MakeInstance and the SingletonHolder::Instance in the class body
    2-Consider the following:
    static T& Instance()
    {
        if (!pInstance_)
        {
            MakeInstance();
        }
               
        return *pInstance_;
    }

    I added the following methods:
    template <typename P1, typename P2>
    static T& Instance(P1 p1, P2 p2)
    {
        if (!pInstance_)
        {
            MakeInstance(p1, p2);
        }
       
        return *pInstance_;
    }

    template <typename P1>
    static T& Instance(P1 p1)
    {
        if (!pInstance_)
        {
            MakeInstance(p1);
        }
       
        return *pInstance_;
    }

    template <typename P1, typename P2>
    static void MakeInstance(P1 p1, P2 p2)
    {
        //typename Apply1<ThreadingModel, T>::Lock guard;
        typename Apply1<ThreadingModel, SingletonHolder>::Lock guard;
        (void)guard;

        if (!pInstance_)
        {
            if (destroyed_)
            {
                LifetimePolicy::OnDeadReference(pInstance_);
                destroyed_ = false;
            }
            pInstance_ = CreationPolicy::Create(p1, p2, pInstance_);

            LifetimePolicy::ScheduleDestruction(pInstance_,
                &DestroySingleton);
        }
    }

    template <typename P1>
    static void MakeInstance(P1 p1)
    {
        //typename Apply1<ThreadingModel, T>::Lock guard;
        typename Apply1<ThreadingModel, SingletonHolder>::Lock guard;
        (void)guard;

        if (!pInstance_)
        {
            if (destroyed_)
            {
                LifetimePolicy::OnDeadReference(pInstance_);
                destroyed_ = false;
            }
            pInstance_ = CreationPolicy::Create(p1, pInstance_);

            LifetimePolicy::ScheduleDestruction(pInstance_,
                &DestroySingleton);
        }
    }

    3-Obviously I modified also the CreationPolicy.
    Here follows the CreateUsingNew struct:
    struct CreateUsingNew
    {
        template <class T>
        static T* Create(const volatile T* p = 0)
        {
            return new T();
        }

        template <class T, typename P1>
        static T* Create(P1 p1, const volatile T* p = 0)
        {
            return new T(p1);
        }
       
        template <class T, typename P1, typename P2>
        static T* Create(P1 p1, P2 p2, const volatile T* p = 0)
        {
            return new T(p1, p2);
        }
           
        template <class T>
        static void Destroy(T* p)
        { delete p; }
    };

    I hope this can be interesting for you all.

    Francesco Vitale

     
  • chen shu

    chen shu - 2011-05-06

    This is very useful. I believe most of developers  need this.But why nobody talked about this idea here over the past several years?
    I just viewed the source codes of Loki quickly,it still didn't support this feature. If the maintainers of Loki library don't think it's a not good idea,can you tell us why?
    Thanks.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks