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