C++ Singleton
A singleton class in object-oriented programming is a particular class that only allows the presence of one object or instance at a time. In simple terms, a singleton class prevents the creation of further instances by allowing the creation of only one instance. The new variable refers to the first instance produced in subsequent efforts to establish another instance.
A single instance of the class is the only thing that exists in a singleton class, representing the Singleton design pattern. It upholds the principle that each class should have just one instance and be globally accessible from wherever in the program.
A singleton instance is a singular item that remains singular throughout a program. By adequately utilizing language features like access control, constructors, and static methods, the singleton pattern guarantees the constant presence of a single class instance throughout the program.
Implementation of Singleton Class in C++
- Make each of the class's constructors private.
- Delete the class's copy constructor.
- A private static pointer pointing to an object of the same class should be created as a singleton class.
- Make a public static method that returns a pointer to an object of the same class (singleton class).
Example:
#include <iostream>
using namespace std;
class Singleton {
private:
String person, activity;
static Singleton* instancePtr;
Singleton() {}
Public:
Singleton(const Singleton& obj) = delete;
static Singleton* getInstance() {
if (instancePtr == NULL) {
instancePtr = new Singleton();
return instancePtr;
}
else {
return instancePtr;
}
}
void setInfo(string person, string activity) {
this->person = person;
this->activity = activity;
}
void displayInfo() {
cout << person << " enjoys " << activity << "." << endl;
}
};
Singleton* Singleton::instancePtr = NULL;
int main() {
Singleton* firstPerson = Singleton::getInstance();
firstPerson->setInfo("Alice", "painting");
cout << "Info for firstPerson: ";
firstPerson->displayInfo();
cout << "Address of firstPerson: " << firstPerson << endl;
cout << endl;
Singleton* secondPerson = Singleton::getInstance();
secondPerson->setInfo("Bob", "playing guitar");
cout << "Info for secondPerson: ";
secondPerson->displayInfo();
cout << "Address of secondPerson: " << secondPerson << endl;
return 0;
}
Output:
![C++ Singleton](https://static.tutorialandexample.com/cpp/cpp-singleton1.png)
Case 1: The Singleton Class will be created as an instance.
The getInstance() method in this implementation is designed to pre-create a Singleton class instance during its initialization process. Singleton class creation is accomplished using the new keyword to initialize the instancePtr with an actual instance rather than NULL.
Code:
#include <iostream>
using namespace std;
class Singleton {
private:
String personName, favoriteActivity;
static Singleton* instancePtr;
Singleton() {}
Public:
Singleton(const Singleton& obj) = delete;
static Singleton* getInstance() {
return instancePtr;
}
void setNameAndActivity(string name, string activity) {
personName = name;
favoriteActivity = activity;
}
void displayDetails() {
cout << "Person: " << personName << ", Favorite Activity: " << favoriteActivity << endl;
}
};
Singleton* Singleton::instancePtr = new Singleton();
int main() {
Singleton* firstInstance = Singleton::getInstance();
firstInstance->setNameAndActivity("Alice", "painting");
cout << "Details for firstInstance: ";
firstInstance->displayDetails();
cout << "Address of firstInstance: " << firstInstance << endl;
cout << endl;
Singleton* secondInstance = Singleton::getInstance();
secondInstance->setNameAndActivity("Bob", "playing guitar");
cout << "Details for secondInstance: ";
secondInstance->displayDetails();
cout << "Address of secondInstance: " << secondInstance << endl;
return 0;
}
Output:
![C++ Singleton](https://static.tutorialandexample.com/cpp/cpp-singleton2.png)
Case2: when the Singleton Class is not created using the getInstance() method before creating the instance.
The C++ program for creating a singleton class without utilizing the getinstance() method is shown below:
#include <iostream>
using namespace std;
class Singleton {
private:
String personName, favoriteActivity;
static Singleton* instancePtr;
Singleton() {}
Singleton(string name, string activity) {
personName = name;
favoriteActivity = activity;
}
Public:
Singleton(const Singleton& obj) = delete;
static Singleton* getInstance() {
if (instancePtr == NULL) {
instancePtr = new Singleton();
return instancePtr;
}
else {
return instancePtr;
}
}
void setInfo(string name, string activity) {
personName = name;
favoriteActivity = activity;
}
void displayInfo() {
cout << personName << " enjoys " << favoriteActivity << "." << endl;
}
};
Singleton* Singleton::instancePtr = NULL;
int main() {
// Error: Cannot create an object of Singleton class
// as the default constructor is private and
//No method is used to access it.
Singleton* personInstance = new Singleton();
// Use the getInstance() method to create and access the Singleton instance
Singleton* instance = Singleton::getInstance();
instance->setInfo("John", "programming");
cout << "Details for personInstance: ";
personInstance->displayInfo();
cout << "Details for instance: ";
instance->displayInfo();
return 0;
}
Output:
![C++ Singleton](https://static.tutorialandexample.com/cpp/cpp-singleton3.png)
Explanation: The Singleton design pattern is implemented in C++ using the provided code. Only one instance of the Singleton class may be generated. It keeps an instance pointer that is static and initially set to NULL (instancePtr). The class's public getInstance() method makes it possible to obtain the instance.
If an instance is requested, the method either creates one if none exists or returns the current instance. Direct instantiation is prevented by the private constructor's Singleton() and Singleton(string, string). The main() function uses getInstance() appropriately to generate and display information about a singleton instance after initially attempting to construct an instance directly (which fails).
Conclusion
The C++ Singleton design pattern ensures a class has a single instance and offers a universal access point to that instance. Singleton limits numerous instantiations and ensures constant access to the single instance throughout the program's execution by using private constructors and a static function to regulate instance generation.
This approach is helpful in situations like managing shared resources or configurations when preserving a single instance is essential. Multi-threading and memory management must be handled carefully to guarantee the pattern's effectiveness and accuracy. Using the Singleton design, C++ programs can effectively manage unique instances and uphold a structured, regulated environment for shared resources.