
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Basic Input/Output
- C++ Manipulators
- C++ Modifier Types
- C++ Storage Classes
- C++ Constexpr Specifier
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Scope Resolution Operator
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Return Values
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Inheritance
- C++ Inheritance
- C++ Multiple Inheritance
- C++ Multilevel Inheritance
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ Design Patterns
- C++ Creational Design Patterns
- C++ Singleton Design Pattern
- C++ Factory Method Design Pattern
- C++ Abstract Factory Pattern
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ unordered_multiset
Singleton Pattern in C++
A Singleton Pattern is a design pattern which allows to create only one object of a class. Instead of allowing the class to create multiple instances everytime it is called, the singleton pattern ensures that only one instance of the class is created and it also provides it a global access point so that it can be accessed from anywhere in the code.
The singleton pattern is useful when exactly one object is needed to coordinate actions across the system. For example, imagine you are in a office and you need to use a printer. Instead of having printer for a each employee, you can have a single printer that is shared by all employees. This way, you can ensure that only one person can use the printer at a time and it also saves resources.
Key Points of Singleton Pattern
Following are the key points of Singleton Pattern −
- It restricts the instantiation of a class to one single instance.
- It provides a global access point to that instance.
- It is often used for managing shared resources such as database connections, configuration settings, logging, etc.
- It can be implemented using lazy initialization, where the instance is created only when it is needed for the first time.
Implementation of Singleton Pattern in C++
There are several ways to implement the Singleton Pattern in C++. Some of the important and common implementations are −
- Lazy Initialization Singleton
- Eager Initialization Singleton (Hungry Singleton)
- Mayers' Singleton
Mostly, the lazy initialization singleton is used as it is more efficient and it also saves memory. However, the eager initialization singleton is simpler and it is also thread-safe. The Mayers' singleton implementation is a very good modern approach for creating singleton classes in C++.
Lazy Initialization Singleton
In this approach, the instance of the class is created only when it is needed for the first time. This can help us in creating only one instance of the class and it also saves memory.
Step to implement Singleton Pattern in C++
Following are the steps to implement Singleton Pattern in C++ −
- Make the constructor of the class private so that it cannot be instantiated from outside the class.
- Then, create a static variable that holds the single instance of the class.
- Create a static method that returns the instance of the class. This method checks if the instance is already created, if not it creates one and returns it. Otherwise, it simply returns the existing instance.
Example of Singleton Pattern in C++
In the below example, we have a Logger class that implements the singleton pattern. The getInstance() method returns the single instance of the Logger class. The log() method is used to log messages.
Let's implement a simple Logger class using Singleton Pattern in C++.
#include <iostream> #include <string> using namespace std; // Lazy Initialization Singleton of Logger class Logger { private: static Logger* instance; Logger() {} public: static Logger* getInstance() { if (instance == nullptr) { instance = new Logger(); } return instance; } void log(string message) { cout << "Log: " << message << endl; } }; // Initialize the static member Logger* Logger::instance = nullptr; // Main function int main() { Logger* logger = Logger::getInstance(); logger->log("This is a log message."); Logger* l1 = Logger::getInstance(); l1->log("This is another log message."); return 0; }
Following is the output of the above program −
Log: This is a log message. Log: This is another log message.
Eager Initialization Singleton(Hungry Singleton) Implementation
In this approach, we create the instance of the class at the time of class loading. This approach is simpler and it is also thread-safe. However, there is a drawback of this approach is that the instance is created even if it is not used, which can lead to resource wastage. So if you are sure that the instance will be used, then this approach is a good choice.
Example of Eager Initialization Singleton Pattern in C++
Let's implement a simple Logger class using Eager Initialization Singleton Pattern in C++.
#include <iostream> #include <string> using namespace std; // Eager Initialization Singleton of Logger class Logger { private: static Logger* instance; Logger() {} public: static Logger* getInstance() { return instance; } void log(string message) { cout << "Log: " << message << endl; } }; // Initialize the instance at the time of class loading Logger* Logger::instance = new Logger(); // Main function int main() { Logger* logger = Logger::getInstance(); logger->log("This is a log message."); Logger* l1 = Logger::getInstance(); l1->log("This is another log message."); return 0; }
Following is the output of the above program −
Log: This is a log message. Log: This is another log message.
Mayers' Singleton Implementation
The Mayers' Singleton implementation is a very good modern approach for creating singleton classes in C++. This approach uses a static local variable inside the getInstance()
method to hold the single instance of the class. The instance is created when the method is called for the first time and it is destroyed automatically when the program exits. This approach is thread-safe and it also ensures that only one instance of the class is created.
Example of Mayers' Singleton Pattern in C++
Let's implement a simple Logger class using Mayers' Singleton Pattern in C++.
#include <iostream> #include <string> using namespace std; // Mayers' Singleton of Logger class Logger { private: Logger() {} public: static Logger& getInstance() { static Logger instance; return instance; } void log(string message) { cout << "Log: " << message << endl; } }; // Main function int main() { Logger& logger = Logger::getInstance(); logger.log("This is a log message."); Logger& l1 = Logger::getInstance(); l1.log("This is another log message."); return 0; }
Following is the output of the above program −
Log: This is a log message. Log: This is another log message.
Real-world use cases of Singleton Pattern
Following are some real-world use cases of Singleton Pattern −
- Logger class − As we have seen in the examples, the logger class uses the singleton pattern, so it can be accessed anywhere but creates only one instance throughout the application.
- Configuration class − A configuration class can be implemented as a singleton to ensure that there is only one instance of the configuration settings throughout the application.
- Database connection class − Another usecase is to implement a database connection class, so that you don't need to create multiple connections to the database.
- Printer Spooler − A printer spooler can be implemented as a singleton to manage print jobs in a centralized manner. So, your whole system has only one instance of the printer spooler instead of making multiple instances for every application on the system.
Conclusion
In this chapter, we covered in detail the Singleton Pattern in C++. We explained how to implement it and also provided an example of a Logger class that uses the singleton pattern. The singleton pattern is a useful design pattern which helps in managing shared resources and it also ensures that only one instance of a class is created.