tags:

views:

184

answers:

4

Can a singleton class be inherited. if yes, then how can we do it?

EDIT:I mean to say that if we have a class which uses singleton design pattern,then can it be inherited?

+1  A: 

Singleton classes are meant to be inherited. The singleton pattern isn't of much value without inheritance.

  1. Define a mostly abstract base class with a static instance() member function.
  2. Define one or more derived classes that implement the base interface.
  3. Implement instance() to decide at runtime which class to instantiate and return.
Marcelo Cantos
None of my singletons are inherited, yet the seem quite useful. Don't confuse a pattern with a implementation.
anon
Some would say that what you are describing is really a combination of Singleton and Factory, and not just Singleton alone. But I agree that Singleton without Factory is usually an anti-pattern.
Kristopher Johnson
I agree with Kristopher. This is technically not the Singelton pattern. But then again this is how I do it because without the ability to instanciate (or register) different singeltons in different situations (1 per application context [app/test etc]) it becomes impossable (or very hard) to test the system.
Martin York
If you read the [GoF's](http://en.wikipedia.org/wiki/Design_Patterns) exposition of the pattern, inheritance is noted as a motivation of primary importance. It is difficult to tell whether they consider it a prerequisite, but I've always taken it as such.
Marcelo Cantos
+2  A: 

singleton has private constructor so inheritance is not possible. besides singleton has static methods to instantiate private instance member and since you can't override static methods it would be pointless to inherit from singleton.

grapkulec
Singleton's normally have a protected constructor.
Marcelo Cantos
We don't have the same singleton then. If protected, you have no guarantee of uniqueness.
Matthieu M.
Fabio Ceconello
BTW, Alexandrescu implements it as a template, not a base class, and so gives it the name 'SingletonHolder'.
Fabio Ceconello
+1  A: 

It depends on how is your implementation for the design pattern. The simplest form is to make a class like this:

class MySingleton
{
    public:
        static MySingleton &getInstance()
        {
            static MySingleton instance;            
            return instance;
        }
    private:
        MySingleton();
        ~MySingleton();
};

In this case, it can't be inherited because the derived class has no access to its constructor. You could make the constructor protected, but this will enable other derived classes to be non-singleton at will, which can be messy from a design perspective. But usually this simple form is not the preferred way to implement singletons since you have not much control about its lifetime and it's difficult to properly handle dependencies between singletons - not to mention possible multithreading issues. The book Modern C++ Design (http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315/ref=sr_1_1?ie=UTF8&s=books&qid=1270652521), among others, has better implementations; they are template-based and the template instantiation is what makes the object a singleton (and its parameter is the class that will be made singleton). This makes easier to do what you want, since the 'singleton-ness' is detached from the class itself. But nonetheless I think you'd need some policy (possibly enforced by code) to avoid that some class derived from a singleton would be non-singleton, which is difficult to implement.

My recommendation would be to have abstract base classes as ancestors for your singletons, and put the commom behaviour in them, not in the singleton itself, and have the singleton always as the 'final' class (borrowing this meaning from Java).

Fabio Ceconello
A: 

I have a Singleton class that I inherit from in many instances.

Here is the Singleton:

template <class Target>
class Singleton_Shared_Ptr
{
    //---------------------------------------------------------------------
    //  Public Constructors & Destructors
    //---------------------------------------------------------------------
  public:
    //! Destructor.
    virtual         ~Singleton_Shared_Ptr();

    //---------------------------------------------------------------------
    //  Public methods
    //---------------------------------------------------------------------
  public:
    //! Returns a pointer to the instance.
    static boost::shared_ptr<Target>    ptr(void);

    //! Returns a reference to the instance.
    static Target &                     ref(void);

    //---------------------------------------------------------------------
    //  Protected methods
    //---------------------------------------------------------------------
  protected:
    //! Default constructor.
                    Singleton_Shared_Ptr();

    //---------------------------------------------------------------------
    //  Private methods
    //---------------------------------------------------------------------
  private:
     //! Copy constructor, not implemented.
     /*! The copy constructor is declared so that the compiler will not
      *  automatically generate one.
      */
                   Singleton_Shared_Ptr(const Singleton_Shared_Ptr& s);

     //! Assignment operator, declared but not defined.
     /*! The assignment operator is declared so that the compiler will not
      *  automatically generate one.
      */
    Singleton_Shared_Ptr&     operator=(const Singleton_Shared_Ptr& s);

    //---------------------------------------------------------------------
    //  Private members
    //---------------------------------------------------------------------
  private:
    static wxMutex                      m_instance_mutex;
};

template<class Target>
wxMutex                     Singleton_Shared_Ptr<Target>::m_instance_mutex;

//-------------------------------------------------------------------------
//  Singleton_Shared_Ptr Constructors & Destructors
//-------------------------------------------------------------------------
template <class Target>
inline
Singleton_Shared_Ptr<Target> ::
Singleton_Shared_Ptr()
{
}


template <class Target>
inline
Singleton_Shared_Ptr<Target> ::
~Singleton_Shared_Ptr()
{
}


//-------------------------------------------------------------------------
//  Singleton_Shared_Ptr methods in alphabetical order
//-------------------------------------------------------------------------
template <class Target>
boost::shared_ptr<Target>
Singleton_Shared_Ptr<Target> ::
ptr(void)
{
    static boost::shared_ptr<Target>    p_instance;
    if (p_instance.get() == NULL)
    {
        wxMutexLocker   lock(m_instance_mutex);
        if (!p_instance)
        {
            p_instance.reset(new Target);
        }
    }
    return p_instance;
}


template <class Target>
Target &
Singleton_Shared_Ptr<Target> ::
ref(void)
{
    return *(ptr());
}

Here is the usage of the singleton:

class Manager
    : public Singleton_Shared_Ptr<Manager>
{
    //---------------------------------------------------------------------
    //  Friends
    //---------------------------------------------------------------------
    friend class Common::Singleton_Shared_Ptr<Manager>;

    //---------------------------------------------------------------------
    //  Public Constructors and Destructors
    //---------------------------------------------------------------------
  public:
    //! destructor
    virtual                 ~Manager();

    //---------------------------------------------------------------------
    //  Protected Methods
    //---------------------------------------------------------------------
  protected:
    //! Constructor
                                Manager();

    //! Copy constructor -- declared but not implemented.
                                Manager(const Manager& m);

    //! Assignment operator -- declared but not implemented.
    Manager&                    operator= (const Manager& m);
};
Thomas Matthews