3

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

3
  • 6
    Yes. class A : public Singleton { ... }; Commented Apr 7, 2010 at 14:38
  • 3
    I think Neil is trying to say that we need more information. Something along the lines of 'I have a singleton that looks like this ... and I want to inherit it to make it do the following ...' Commented Apr 7, 2010 at 14:40
  • 1
    There is no "the" Singleton to ask questions about, it depends on your implementation of the pattern. If you even need to the pattern. (Hint: you don't). jalf.dk/blog/2010/03/… Commented Apr 7, 2010 at 14:57

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Singleton's normally have a protected constructor.
We don't have the same singleton then. If protected, you have no guarantee of uniqueness.
@Marcelo: what I, Matthieu & others are calling 'singleton' is the class which has only one instance, and you're calling 'Singleton' the abstract base that has the support code for singletons. I think it would be more appropriate to call it 'SingletonBase' since that class is not the singleton itself - the singleton is the concrete class.
BTW, Alexandrescu implements it as a template, not a base class, and so gives it the name 'SingletonHolder'.
3

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

1 Comment

This link is pretty helpful as well: yolinux.com/TUTORIALS/C++Singleton.html
1

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.

4 Comments

None of my singletons are inherited, yet the seem quite useful. Don't confuse a pattern with a implementation.
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.
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.
If you read the GoF's 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.
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.