Singleton pattern is a design pattern which restricts a class to instantiate its multiple objects. It is nothing but a way of defining a class. Class is defined in such a way that only one instance of the class is created in the complete execution of a program or project. It is used where only a single instance of a class is required to control the action throughout the execution. A singleton class shouldn’t have multiple instances in any case and at any cost. Singleton classes are used for logging, driver objects, caching and thread pool, database connections. (or like random number generator, which only seed once)
- It should have only one instance
- Instance should be globally accessible
Singleton class can be instantiated by two methods: - Early initialization : In this method, class is initialized whether it is to be used or not. The main advantage of this method is its simplicity. You initiate the class at the time of class loading. Its drawback is that class is always initialized whether it is being used or not. - Lazy initialization : In this method, class in initialized only when it is required. It can save you from instantiating the class when you don’t need it. Generally, lazy initialization is used when we create a singleton class.
Potentially why this should be a class? we are not intialising more than once right?
In languages like Java, OOPS is forced upon you. If you need some class that should have only one instance
then you have to go with singleton.
Why do we need this in the case of CPP
?
In singleton there is some data and few function enclosed and we intialise once. If we have some global variables
and some fuction that access the global variables, then we can use singleton to group them. Consider a random
number generator , we initialise it once and ask it for random numbers throughout the section.
A very basic Implementation.
#include <iostream>
class Singleton
{
public:
// get the instance
static Singleton& Get()
{
return s_instance;
}
// do something
void Function() {}
private:
// Constructor is private
Singleton() {}
// a static instance
static Singleton s_instance;
};
// creating a instance
Singleton Singleton::s_instance;
int main()
{
// acess the instance
Singleton::Get().Function();
}
// # Note: This is weird captian
// if we try to assign the instance
// what it basically does is create
// a new class named instance
// this defeats the purpose of Singleton
Singleton instance = Singleton::Get();
// So what to do?
public:
// delete the copy constructor
Singleton (const Singleton&) = delete;
// so you can't copy
// instead we can reference
Singleton& instance = Singleton::Get()
Now we expand the it a bit more.
// instead of intializing it outside you can do it inside the function
class Singleton
{
public:
// get the instance
static Singleton& Get()
{
// as it is static it is instantiated once
// this is more cleaner.
static Singleton instance;
return instance;
}