2014-01-29 4 views
4

Работает ли Meyers Singleton в сценарии с динамическими библиотеками?
I.e. одна библиотека, определяющая одноэлемент, другие, использующие ее, каждая в своей собственной единице компиляции?
(Я предполагаю, что это не имеет значения, но специфическая архитектура представляет собой приложение с рамками на OS X)Meyers singleton и динамические библиотеки

Я использую шаблон ваниль Meyers Singleton: Следующий Instance() метод определен встроенным в заголовочном файле для грузового класса (который определяется в виде динамической библиотеки):

static Logger& Instance() 
       { 
       static Logger singletonInstance; 
       return singletonInstance; 
       } 

конструктор копирования и operator= объявлены приватным и не реализованы, поэтому мы должны быть хорошо, верно?

Теперь, если я свяжу эту библиотеку, определяющую синглтон из основного приложения я могу видеть конструктор вызывается несколько раз .. с разными адресами для this и все странности, я бы ожидать, когда не имея фактический синглтон, но множественный экземпляры класса.

Так что я интересно ли динамические библиотеки подход винты вверх одноэлементные Meyers или каждый единица компиляции - библиотека, основное приложение - которое включает в себя заголовок для одноточечного (эффективно объявляющих и определяющего в Instance() метод) получит «собственный экземпляр Singleton»?

Действительно не совсем уверен, что делать с моими наблюдениями, поэтому любые намеки очень ценятся!

+0

Является ли 'static Logger & Instance()' в файле заголовка, который предполагается использовать для получения экземпляра в другом коде? Почему это не «экстерн»? – txtechhelp

+0

- это реальный код? Я ожидал 'Logger :: Instance()' .. –

+0

@KarolyHorvath Да, 'Instance()' определен inline в файле заголовка singleton. Перефразировал вопрос, чтобы сделать это более ясным. – ATV

ответ

9

Вы должны объявитьInstance в заголовке, а затем определить его в динамической библиотеке (предположительно то же самое, что Logger определяются в). И вам нужно сбросить static. И вы должны убедиться, что Instance имеет видимость по умолчанию, если вы используете visibility tools.

Из вашего описания, похоже, что вы определили эту функцию в заголовке. Это даст каждому, кто включает заголовок, свое собственное частное определение Instance, и, таким образом, их собственное частное определение static Logger в пределах Instance.

Вы можете объявить Instanceinline, и это даст все семантика, которую вы ожидаете (то же, что и объявление в заголовке и определение в dylib). Но моя рекомендация состоит в том, чтобы просто сделать inline, чтобы подтвердить, что я говорю вам, правильно (это легко), а затем очертить в dylib (и подтвердить снова).

Как только вы очертите, ваш дизайн должен работать нормально.

Это, как говорится, гарантируется только на C++ 11. То есть, локальная статика не является потокобезопасной в C++ 98/03, но находится на C++ 11 и более поздних версиях. Однако в OS X они являются потокобезопасными даже в языке C++ 03 в качестве расширения.

Еще один нюанс: если доступ Instance() в atexit цепи (или в деструктор глобального объекта), то возможно, что ваш доступ будет происходить после разрушения статической локальной singletonInstance в Instance(), вызывая неопределенное поведение.Если вы не регистрируете вещи с помощью atexit(), и если ваши глобальные деструкторы не звонят Instance(), вы в безопасности. В противном случае это не так. Если вы не в безопасности, вы можете целенаправленно просачиваться его:

Logger& Instance() 
{ 
    static Logger* singletonInstance = new Logger; 
    return *singletonInstance; 
} 

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

+0

Спасибо за разъяснение! Отбрасывание 'static' только в определении, правильно? То есть не имеет смысла снимать его с декларации? – ATV

+1

Выдайте 'static' из описания функции * и * определения. 'static 'в этом контексте означает« область файла »или« частный для файла ». И вы хотите, чтобы область применения этой функции была широкой. –

Смежные вопросы