Иногда при разработке приложений возникает потребность в
существовании некоего объекта, который должен быть доступен из многих,
совершенно разных частей программы. Примером такого объекта может
служить общий контейнер внутренней конфигурации программы. Кроме того,
ключевой особенностью такого объекта является единственность его
существования – к примеру, объект, работающий с определенным COM портом
должен существовать в единственном экземпляре.
Таким образом, мы можем выделить две особенности объекта типа Singleton:
- Доступность объекта из различных частей программы
- Единственность существования
Специально выделяю вторую особенность, дабы подчеркнуть суть такого
объекта. Первая особенность – просто «полезность», вытекающая из
единственности. На практике, эти две особенности идут рядом, поэтому я
не буду разделять их детали реализации.
Да, вопрос об обоснованности существования таких объектов и т.п. –
это совсем другая тема и философия проектирования. Но мы сейчас не об
этом.
Существует несколько подходов к реализации таких объектов. Я
предлагаю один из них, которым пользуюсь уже на протяжении многих лет.
14 | #pragma warning(disable : 4355) |
29 | uSingleton(T& rObject) |
31 | Q_ASSERT_X(!s_pInstance, "constructor" , "Only one instance of this class is permitted." ); |
32 | s_pInstance = &rObject; |
39 | Q_ASSERT_X(s_pInstance, "destructor" , "The singleton instance is invalid." ); |
47 | Q_ASSERT_X(s_pInstance, "instancing" , "The singleton has not yet been created." ); |
48 | return (*s_pInstance); |
54 | static T* s_pInstance; |
58 | uSingleton( const uSingleton& Src); |
59 | uSingleton& operator=( const uSingleton& Src); |
62 | template < class T> T* uSingleton<T>::s_pInstance = 0; |
64 | #endif // A_SINGLETON_H |
Объявление класса:
05 | #ifndef USINGLETONUSERCLASS_H |
06 | #define USINGLETONUSERCLASS_H |
10 | #include "a_singleton.h" |
14 | #define MY_CLASS MyClass::instance() |
19 | class MyClass : public QObject, public uSingleton<MyClass> |
24 | explicit MyClass(QObject* parent = 0); |
30 | #endif // USINGLETONUSERCLASS_H |
Не забудьте инициализировать синглетон в конструкторе:
04 | MyClass::MyClass(QObject *parent) |
05 | : QObject(parent), uSingleton<MyClass>(* this ) |
Теперь доступ к объекту класса производится простым и понятным путем:
Источник: http://ufna.ru/2010/04/24/singleton-for-qt |