Как вы выбираете между синглтоном и безымянным классом? - PullRequest
3 голосов
/ 28 декабря 2008

Я бы использовал синглтон вот так:

Singleton* single = Singleton::instance();
single->do_it();

Я бы использовал такой безымянный класс:

single.do_it();

Мне кажется, что шаблон Singleton не имеет никакого преимущества над неназванным классом, кроме наличия читаемых сообщений об ошибках. Использование синглетонов неудобнее, чем использование безымянного объекта класса: во-первых, клиенты должны сначала получить дескриптор экземпляра; во-вторых, разработчику Singleton::instance() может потребоваться учитывать параллелизм.

Так почему и как бы вы выбрали синглтон вместо безымянного класса?

В качестве дополнения, хотя очевидное определение неназванного класса может быть

class {
    // ...
}single;

Я мог бы также определить это так:

#ifndef NDEBUG
class Singleton__ {   // readable error messages,
#else
class {               // unnamed, clients can't instantiate
#endif
    // ...
}single;

с последним подходом, который имеет преимущество читаемых сообщений об ошибках компилятора, но не является одиночным в режиме отладки.

Ответы [ 8 ]

8 голосов
/ 28 декабря 2008

Я думаю, что наиболее важной причиной является то, что вы не можете поместить безымянный класс в область имен. Таким образом, следующее недопустимо (gcc принимает, но предупреждает. Comeau не принимает в строгом режиме):

class { } single;
int main() { }

Тип single имеет связь no , потому что нет способа объявить его имя в другой области, ссылающейся на него (именно потому, что у него нет имени). Но использование его для объявления single, у которого есть связь (внешняя здесь), недопустимо (3.5 / 8). single должен быть определен локально в main, где он не будет иметь никакой связи. Вы также не можете передать одиночный шаблон функции и у него не может быть статических элементов данных (потому что нет способа определить их). Все эти ограничения делают его более или менее неприменимым в качестве замены одиночного.

4 голосов
/ 28 декабря 2008

Конечно, главная причина использования одноэлементных объектов в C ++ - дать вам некоторый контроль над порядком инициализации, используя «ленивую конструкцию» в вашем методе экземпляра?

В качестве примера, большая часть моего кода использует одиночный журнал, в который записываются сообщения журнала. Это началось много месяцев назад как старый добрый «глобал», но после того, как его укусила попытка использовать его перед строительством, теперь он является синглтоном:

раньше ...

logger.write("Something bad happened..."); // crash if logger not constructed

... * после 1008 *

 Logger &getLogger()
 {
   static Logger logger_;
   return logger_;
 }

 getLogger().write("Something bad happened...");

Я читал обычные посты "singletons is bad", но никто не видел, чтобы кто-нибудь предлагал лучшую альтернативу для C ++.

2 голосов
/ 28 декабря 2008

Синглтон-класс, который вы можете объявить в заголовке и реализовать в cxx, и, следовательно, использовать его в файлах cxx. Вы не можете сделать это с безымянным классом, так как каждый cxx будет пытаться иметь свой собственный экземпляр объекта.

1 голос
/ 28 декабря 2008

По вашему вопросу я вижу, что вы не совсем понимаете природу и цель паттерна Синглтона.

Вы используете singleton, если хотите, чтобы объект global был доступен для многих «клиентов», и вы хотите быть уверенным, что создан только один экземпляр этого объекта. Возьмем, к примеру, объект логгера. Вы хотите иметь возможность регистрироваться из любой части вашего кода, но в вашем проекте должен быть только один регистратор. Это идеальное место для синглтона.

Ваш пример выглядит так, как будто вы создаете локальный объект с небольшой областью действия. Для этого синглтон не нужен. Это делает код намного более понятным и легким для чтения.

1 голос
/ 28 декабря 2008

Хотя это удобно, синглтоны обычно плохая идея . См. эту страницу для замены дизайна.

1 голос
/ 28 декабря 2008

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

0 голосов
/ 28 декабря 2008

использовать синглтоны. используйте const. инициализируйте их все в один класс бога. знать об этом и избегать статического порядка инициализации фиаско: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

0 голосов
/ 28 декабря 2008

если (кроме многословности ошибок) нет различий в поведении, глобальный экземпляр требует 1 дополнительного LOC, для синглтона потребуется набор нетривиальных шаблонов. KISS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...