Search code examples
c++design-patternssingletonsingle-instance

not global Singleton design pattern?


Possible Duplicate:
A Singleton that is not globally accessible

Do you know a good design pattern that would make sure that only one instance of an object is created without making this object global in c++? That's what singleton do but I really need it NOT to be global for code access security reasons.

Thanks for your help!


Solution

  • I think you want something like this (note: copy-pasted from an answer I already wrote and forgot about):

    #include <stdexcept>
    
    // inherit from this class (privately) to ensure only
    // a single instance of the derived class is created
    template <typename D> // CRTP (to give each instantiation its own flag)
    class single_instance
    {
    protected: // protected constructors to ensure this is used as a mixin
        single_instance()
        {
            if (mConstructed)
                throw std::runtime_error("already created");
    
            mConstructed = true;
        }
    
        ~single_instance()
        {
            mConstructed = false;
        }
    
    private:
        // private and not defined in order to
        // force the derived class be noncopyable
        single_instance(const single_instance&);
        single_instance& operator=(const single_instance&);
    
        static bool mConstructed;
    };
    
    template <typename T>
    bool single_instance<T>::mConstructed = false;
    

    Now you get an exception if the class is constructed more than once:

    class my_class : private single_instance<my_class>
    {
    public:
        // usual interface (nonycopyable)
    };
    
    int main()
    {
        my_class a; // okay
        my_class b; // exception
    }
    

    There's no way to enforce the single-instance policy at compile-time in C++, though.


    (Also good on you for noticing that singletons are dumb. Globally accessible and singly-creatable are two different concepts, and should only be combined by coincidence, not by design.)