Vijay
Vijay

Reputation: 67211

C++-Singleton class

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?*

Upvotes: 3

Views: 3569

Answers (4)

Thomas Matthews
Thomas Matthews

Reputation: 57678

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);
};

Upvotes: 0

Fabio Ceconello
Fabio Ceconello

Reputation: 16039

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).

Upvotes: 3

grapkulec
grapkulec

Reputation: 1020

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.

Upvotes: 4

Marcelo Cantos
Marcelo Cantos

Reputation: 185852

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.

Upvotes: 1

Related Questions