Паттерн проектирования Singleton обеспечивает создание одного единственного экземпляра класса и предоставляет глобальную точку доступа к этому экземпляру. Вот как можно реализовать и использовать паттерн Singleton в языке C++:
Реализация паттерна Singleton
- Скрытый конструктор: Конструктор класса должен быть приватным или защищенным, чтобы предотвратить создание объектов извне.
- Удаленные копирующие конструкторы: Запретите копирование и присваивание объектов, чтобы гарантировать, что только один экземпляр будет создан.
- Статическая функция-член: Статическая функция-член возвращает указатель на единственный экземпляр класса.
- Статический экземпляр: Экземпляр класса должен быть создан как статический член.
Пример кода:
#include <iostream>
#include <mutex>
class Singleton {
private:
static Singleton* instance;
static std::mutex mtx;
// Приватный конструктор
Singleton() {
std::cout << "Создание экземпляра Singleton" << std::endl;
}
// Удаленные копирующий конструктор и оператор присваивания
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
// Статическая функция, возвращающая единственный экземпляр
static Singleton* getInstance() {
std::lock_guard<std::mutex> lock(mtx); // Блокировка для обеспечения потокобезопасности
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
void doSomething() {
std::cout << "Метод doSomething вызван" << std::endl;
}
};
// Инициализация статических членов класса
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
int main() {
// Получение единственного экземпляра Singleton
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
// Проверка, что экземпляры одинаковы
if (s1 == s2) {
std::cout << "Оба указателя указывают на один и тот же экземпляр" << std::endl;
}
// Вызов метода doSomething
s1->doSomething();
return 0;
}
Объяснение кода
- Приватный конструктор:
- Конструктор класса
Singleton
объявлен как приватный, чтобы запретить создание объектов извне.
- Удаленные копирующие конструкторы:
- Копирующий конструктор и оператор присваивания объявлены как удаленные (
= delete
), чтобы предотвратить копирование и присваивание объектов.
- Статическая функция-член:
- Функция
getInstance()
возвращает указатель на единственный экземпляр класса. Она использует блокировку (std::lock_guard
), чтобы обеспечить потокобезопасность.
- Статический экземпляр:
- Экземпляр класса
Singleton
и объектstd::mutex
объявлены как статические члены.
- Использование Singleton:
- В функции
main()
вызываетсяgetInstance()
для получения единственного экземпляра класса. Оба указателяs1
иs2
указывают на один и тот же объект, что подтверждает правильную работу паттерна Singleton.
Преимущества паттерна Singleton
- Контроль доступа:
- Паттерн Singleton гарантирует, что существует только один экземпляр класса, и предоставляет глобальную точку доступа к нему.
- Экономия ресурсов:
- Позволяет избежать многократного создания объекта, что может быть особенно полезно для ресурсоемких объектов.
- Гарантия инициализации:
- Паттерн Singleton обеспечивает правильную инициализацию объекта и предотвращает создание его копий.
Заключение
Паттерн Singleton — это эффективный способ управления доступом к единственному экземпляру класса в приложении. Он помогает контролировать инициализацию, экономить ресурсы и обеспечивать глобальную точку доступа к объекту.