Page 50 - 4190
P. 50
Клієнти патерну Singleton отримують єдиний об'єкт класу через
статичну функію-член, яка при першому запиті динамічно виділяє
пам'ять під цей об'єкт і потім повертає вказівник на цю ділянку пам'я-
ті. У результаті клієнти повинні самі потурбуватися про звільнення
пам'яті за допомогою оператора delete.
Остання особливість є серйозним недоліком класичної реалізації
шаблону Singleton. Оскільки клас сам контролює створення єдиного
об'єкту, було б логічним покласти на нього відповідальність і за ви-
далення об'єкту. Цей недолік відсутній в реалізації Singleton, уперше
запропонованій Скоттом Мэйерсом.
Всередині методу getInstance() використовується статичний екзе-
мпляр потрібного класу. Стандарт мови програмування C++ гарантує
автоматичне знищення статичних об'єктів при завершенні програми.
Дострокове знищення і не потрібне, оскільки об'єкти Singleton зазви-
чай є довгоживучими об'єктами. Статична функція-член getInstance()
повертає не вказівник, а посилання на цей об'єкт, тим самим, утруд-
няючи можливість помилкового звільнення пам'яті клієнтами.
Приведена реалізація патерну Singleton використовує так звану
відкладену ініціалізацію (lazy initialization) об'єкту, коли об'єкт класу
ініціалізувався не при старті програми, а при першому виклику
getInstance(). У даному випадку це забезпечується тим, що статична
змінна instance оголошена всередині функції-члена класу
getInstance(), а не як статичний член даних цього класу.
На жаль, у реалізації Мэйерса є недоліки: складнощі створення
об'єктів похідних класів і неможливість безпечного доступу декількох
клієнтів до єдиного об'єкту у багатопотоковому середовищі.
З урахуванням усього вищесказаного класична реалізація патерну
Singleton може бути поліпшена шляхом введення класу
SingletonDestroyer, призначеного для автоматичного знищення об'єк-
ту Singleton. Клас Singleton має статичний член SingletonDestroyer,
який ініціалізується при першому виклику getInstance() створюваним
об'єктом Singleton. При завершенні програми цей об'єкт буде автома-
тично зруйнований деструктором SingletonDestroyer (для цього
SingletonDestroyer оголошений другом класу Singleton).
Для запобігання випадкового видалення користувачами об'єкту
класу Singleton, деструктор не роблять загальнодоступним, як раніше.
Він оголошений захищеним.
Досі передбачалося, що в програмі використовується один клас
Singleton або декілька незв'язаних між собою. При використанні вза-
50