Re[2]: Синглтон через умный указатель
От: Alexander G Украина  
Дата: 07.03.09 12:27
Оценка: 1 (1) +1
Здравствуйте, MescalitoPeyot, Вы писали:

MP>Здравствуйте, pegarus, Вы писали:


P>>Подскажите, как называется приведённая ниже реализация синглтона? Какие есть недостатки в отличие от синглтона Маерса?


MP>Она называется велосипед с проблемами. Например, не потокобезопасный счетчик первое что бросается в глаза


+1

Однако, преимущества этого подхода перед СМ есть.

operator-> делает более сложным сохранение ссылки/указателя на синглтон.

Т.е. в случае X::Instance().Method() можно написать X& x = X::Instance(); в случае X::instance->Method() это уже сложнее.

Ссылки вида CSingle считаются, так, в отличии от СМ, ситнглтон не будет использован после удаления, а после удеаления последней ссылки если он снова нужен он снова создаётся (разумеется, не-потокобезоасность всё ломает).

Далее, в отличии от СМ этот, похоже, готов к бросающему конструктору.

---

Я пришел к выводу, что лучше синглтон с таким интерфейсом в хедере:

namespace my_singleton
{
  T1 method1(P1);
  T2 method2(P2);
  ...
}


Т.е. никаких приватных методов и дата мемберов (как преимущества pImpl), плюс нельзя вообще никак взять его адрес или попытаться скопировать.
И меньше возможностей нарушить ABI незаметно для компоновщика в случае, например, TCHAR дата memberов:
class X : public Singleton<X>
{
  ...
  TCHAR path[MAX_PATH]; 
} // имплементация c _UNICODE, инстанциируем без _UNICODE - happy debugging :)


Имплементация в .cpp в зависимости от потребностей. Неплохо её запихнуть в глобальную переменную в неймспейс детейл:

namespace my_singleton{namespace detail{
  struct data {
    ...
  } = {};
}}



тогда в отладчике в Watch работает в любом месте:
my_singleton::detail::data

(в том числе и в минидампе с MiniDumpWithDataSegs)

Т.к. статической инициализации редко достаточно, нужно как-то обеспечить динамическую инициализацию/финализацию. Тут в зависимости от потребностей, разное можно сделать: boost::call_once, что-то вроде Синглтона Мейерса, но форсированое конструктором глобального объекта, более интересные трюки. Для финализации может быть полезен прямой вызов atexit.

Т.е. имплементация каждый раз по месту, зависит от конкретного случая, и может быть изменена действительно незаметно для клиента — без перекомпиляции его кода. И никакой шаблонной магии.

Где я бы такое применял. Можно условно разделить синглтоны на:
1. "Глобальные переменные" — менеджеры памяти, врапперы к системным сервисам, жучки для отладки — то что действительно по-любому синглтон. Тут вышеописанный интерфейс синглтона рулит.
2. "Ошибки проектирования" — Классы, содержащие логику приложения, которые всвязи с текущим дизайном сделаны синглтонами, но дизайн может поменятся. Тут лучше сделать синглтонность CRTP-базой.
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.