Обов’язковим питанням на співбесідах є «Які патерни проєктування вам відомі?». Найпростішим з них є синглтон Мейерса (Meyers’ Singleton), або просто «синглтон» чи «одинак». Концепція полягає в тому, щоб створити глобально доступний об’єкт класу, і гарантувати, що він буде лише один. «Глобальним об’єктом» може бути будь-що: база даних, список об’єктів чи унікальний фізичний пристрій.
Як приклад, припустимо певна система має вбудований дисплей і дозволяє доступитись до його характеристик через певний складний програмний інтерфейс. Створіть клас-синглтон Display, який приховує цей складний інтерфейс, і дає простий доступ до характеристик. Для цього потрібно:
- Визначити сам клас Display з його характеристиками — трьома звичайними public полями:
- w — width, ширина дисплею в пікселях, 1920 за замовчуванням.
- h — height, висота дисплею в пікселях, 1080 за замовчуванням.
- f — frequency, частота дисплею в герцах, 120 за замовчуванням.
(Примітка: припускаємо, що ці значення отримали певним складним способом шляхом виклику сторонніх функцій).
- Визначити конструктор за замовчуванням і деструктор як private. Їх можна явно оголосити як default.
- Явно видалити конструктор копіювання і переміщення, щоб не мати можливості випадково створити інший об’єкт.
- Визначити public static функцію instance(), яка конструює статичну змінну типу Display за замовчуванням і повертає константне посилання на неї.
Що отримаємо в результаті:
- private конструктор та деструктор і видалені конструктори гарантують єдиність об’єкта: поза межами класу не можна явно створювати чи видаляти об’єкт типу Display.
- static функція instance() зі статичною змінною типу Display конструює єдиний об’єкт і дає глобальну точку доступу до нього.
- instance() повертає константе посилання, тому поля також ніяк не можна змінити. Загалом кажучи, посилання не обов’язково має бути константним, це вже залежить від потреб проєкту.
За умови коректного оголошення, наступний код мав би вивести «1920×1080@120»:
#include <iostream>
class Display {
/* ... */
};
int main() {
std::cout << Display::instance().w << 'x'
<< Display::instance().h << '@'
<< Display::instance().f << std::endl;
return 0;
}
Відповідь:
#include <iostream>
class Display {
public:
int w = 1920;
int h = 1080;
int f = 120;
static const Display& instance() {
static const Display o{};
return o;
}
private:
Display() = default;
Display(const Display&) = delete;
Display(Display&&) = delete;
~Display() = default;
};
int main() {
std::cout << Display::instance().w << 'x'
<< Display::instance().h << '@'
<< Display::instance().f << std::endl;
return 0;
}
Добавить комментарий