Saturday, February 4, 2012

C++ Design Pattern: What is a Singleton class?

Source

Q: What is a singleton class?

A: A class whose number of instances that can be instantiated is limited to one is called a singleton class. Thus, at any given time only one instance can exist, no more.



Q: Can you give me an example, where it is used?

A: The singleton design pattern is used whenever the design requires only one instance of a class. Some examples:
  • Application classes. There should only be one application class. (Note: Please bear in mind, MFC class 'CWinApp' is not implemented as a singleton class)
  • Logger classes. For logging purposes of an application there is usually one logger instance required.



Q: How could a singleton class be implemented?

A: There are several ways of creating a singleton class. The most simple approach is shown below:

Code:
class CMySingleton
{
public:
  static CMySingleton& Instance()
  {
    static CMySingleton singleton;
    return singleton;
  }

// Other non-static member functions
private:
  CMySingleton() {};                                 // Private constructor
  CMySingleton(const CMySingleton&);                 // Prevent copy-construction
  CMySingleton& operator=(const CMySingleton&);      // Prevent assignment
};


Q: Can I extend the singleton pattern to allow more than one instance?

A: The general purpose of the singleton design pattern is to limit the number of instances of a class to only one. However, the pattern can be extended by many ways to actually control the number of instances allowed. One way is shown below...

Code:
class CMyClass
{
private:
  CMyClass() {}                           // Private Constructor

  static int nCount;                      // Current number of instances
  static int nMaxInstance;                // Maximum number of instances

public:
  ~CMyClass();                            // Public Destructor

  static CMyClass* CreateInstance();      // Construct Indirectly

  //Add whatever members you want
};
  • Here we declare our constructor/s as private, thus denying direct creation of the class.
  • A static function CreateInstance that creates the class indirectly for us.
  • Two static members, one holding the current number of instances, another one the maximum allowed.
  • Note: We have to declare at least one constructor (private - of course), else direct creation will be possible.

Code:
int CMyClass::nCount = 0;
int CMyClass::nMaxInstance = 1;         // When maxInstance is 1, we have a pure singleton class

CMyClass::~CMyClass()
{
  --nCount;                             // Decrement number of instances
}

CMyClass* CMyClass::CreateInstance()
{
  CMyClass* ptr = NULL;

  if(nMaxInstance > nCount)
  {
    ptr = new CMyClass;  
    ++nCount;                           // Increment no of instances
  }
  return ptr;
}
  • Everytime an instance is created, the count is incremented, and when the object is deleted, the destructor is invoked, and the count is decremented.
  • Since, the objective is to limit the number of instances, we allow direct destruction of object.
  • As a special case, when 'maxInstance' is 1, we have a pure singleton class.

Now if you want to create an instance of the class:

Code:
CMyClass* pObj = CMyClass::CreateInstance();
if(pObj)
{
  // Success
}
else
{
  // Failed to create, probably because the maximum number of instances has already been created
}
Note, that the successfully created instance(s) need(s) to be released to ensure that no memory leak occurs:

Code:
delete pObj;

No comments:

Post a Comment