From 986879c1fb40ad9b5ee0c5cec76adb0d2d9ca445 Mon Sep 17 00:00:00 2001 From: Phong Nguyen Date: Mon, 24 Nov 2025 10:52:55 +0700 Subject: [PATCH] Add the Singleton pattern --- CMakeLists.txt | 1 + .../patterns_creational_singleton.drawio.svg | 4 + src/patterns/creational/Singleton.cpp | 87 +++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 docs/uml/patterns_creational_singleton.drawio.svg create mode 100644 src/patterns/creational/Singleton.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e0849e2..d6ab1c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,7 @@ set(APP_SOURCES "src/patterns/behavioral/Strategy.cpp" "src/patterns/behavioral/State.cpp" "src/patterns/behavioral/Observer.cpp" + "src/patterns/creational/Singleton.cpp" ) # Test files diff --git a/docs/uml/patterns_creational_singleton.drawio.svg b/docs/uml/patterns_creational_singleton.drawio.svg new file mode 100644 index 0000000..1b161cf --- /dev/null +++ b/docs/uml/patterns_creational_singleton.drawio.svg @@ -0,0 +1,4 @@ + + + +
Client
+ clientCode(Singleton* s): type
Singleton
- instance: Singleton*
- Singleton()
+ getInstance(): Singleton*

+ operation(Type): Type
Singleton* s1 = Singleton::getInstance();
s1->operation();
Singleton* s2 = Singleton::getInstance();
s2->operation();
getInstance:
{
 if(instance == nullptr){
  instance = new Singleton(); 
 }
 return instance;
}
\ No newline at end of file diff --git a/src/patterns/creational/Singleton.cpp b/src/patterns/creational/Singleton.cpp new file mode 100644 index 0000000..2f15072 --- /dev/null +++ b/src/patterns/creational/Singleton.cpp @@ -0,0 +1,87 @@ +// cppcheck-suppress-file [functionStatic] + +// Singleton is a creational design pattern that lets you ensure that a class has only one instance, +// while providing a global access point to this instance. +// Appicability: +// (*) when a class in your program should have just a single instance available to all clients; for example, a single database object shared by different parts of the program. +// (**) when you need stricter control over global variables. + +#include + +namespace +{ + namespace SingletonPattern + { + + /** + * The Singleton class defines the `GetInstance` method that serves as an + * alternative to constructor and lets clients access the same instance of this + * class over and over. + */ + class Singleton + { + private: + static inline Singleton *instance = nullptr; + static inline int num = 0; + /** + * The Singleton's constructor should always be private to prevent direct + * construction calls with the `new` operator. + */ + Singleton() = default; + + public: + // 1. Should not be cloneable. + Singleton(const Singleton &other) = delete; + + // 2. Should not be assignable + Singleton &operator=(const Singleton &other) = delete; + + static Singleton *getInstance() + { + if (instance == nullptr) + { + instance = new Singleton(); + num++; + } + + return instance; + } + + void operation() const + { + std::cout << "Singleton operating num:" << num << "\n"; + } + }; + + namespace Client + { + void clientCode(const Singleton *const s) + { + s->operation(); + } + } + + void run() + { + const Singleton *s1 = Singleton::getInstance(); + Client::clientCode(s1); + + const Singleton *s2 = Singleton::getInstance(); + Client::clientCode(s2); + + // Singleton* s3 = new Singleton(); // ERROR + } + + } +} + +struct SingletonAutoRuner +{ + SingletonAutoRuner() + { + std::cout << "\n--- Singleton Pattern Example ---\n"; + SingletonPattern::run(); + } +}; + +static SingletonAutoRuner instance; \ No newline at end of file