Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions docs/uml/patterns_creational_singleton.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
87 changes: 87 additions & 0 deletions src/patterns/creational/Singleton.cpp
Original file line number Diff line number Diff line change
@@ -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 <iostream>

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;