Description: D:\website\syllabus\study_matreials\c++\logo_pic\logo.jpg

Singleton Class



 

Q: What is a singleton class / pattern?

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. A design pattern that follows the above principle is called singleton pattern.



Q: Where is this pattern 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 simplest approach is shown below:

class SampleSingleton

{

public:

  static SampleSingleton& CreateInstance()  //You can either return by value or reference  --> static SampleSingleton& CreateInstance()

  {

 

         printf("In the copy constructor ..");

         static SampleSingleton singleton;

      return singleton;

  }

 

  void Display()

  {

         printf("\nThis is just displaying some dummy message:\n");

 

  }

 

// Other non-static member functions

private:

       SampleSingleton(){}                              // Private constructor

       SampleSingleton& operator = (SampleSingleton& refObj);   // Prevent assignment

       SampleSingleton(SampleSingleton& refObj){}                // Prevent copy-construction

};

 

int main(int argc, char* argv[])

{

       SampleSingleton::CreateInstance().Display();

       SampleSingleton obj1(SampleSingleton::CreateInstance()); //--> this is not permitted as copy constructor is made private

       SampleSingleton obj2 = SampleSingleton::CreateInstance(); //--> this is not permitted as copy constructor is made private.

       //Note: The above syntax will call the copy constructor only, not overloaded assignment operator. Overloaded assignment operator is

       //called only when one object is assigned with the other where both are previously created.

       SampleSingleton obj3 = obj1; //--> Not permitted. This will also call the copy constructor

       obj3=obj1;  //--> Not permitted. This will call the overloaded assignment operator

       return 0;

}

 

 


Run in MyWhiteBoard


 

 



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;

 

 

 

Q What happens if return type is given as void for the overloaded assignment opertaior like:

       void operator = (MyClass& refObj) { }

instead of      MyClass& operator = (MyClass& refObj) { }  ?

 

Ans:   if the return type is given as void, it will permit obj1= obj2 but, it will not permit multiple assignment in the same line like obj1=obj2=obj3;

 

Copyright © Open Sky Technology