Иногда при разработке приложений возникает потребность в существовании некоего объекта, который должен быть доступен из многих, совершенно разных частей программы. Примером такого объекта может служить общий контейнер внутренней конфигурации программы. Кроме того, ключевой особенностью такого объекта является единственность его существования — к примеру, объект, работающий с определенным COM портом должен существовать в единственном экземпляре.
Таким образом, мы можем выделить две особенности объекта типа Singleton:
- Доступность объекта из различных частей программы
- Единственность существования
Специально выделяю вторую особенность, дабы подчеркнуть суть такого объекта. Первая особенность — просто «полезность», вытекающая из единственности. На практике, эти две особенности идут рядом, поэтому я не буду разделять их детали реализации.
Да, вопрос об обоснованности существования таких объектов и т.п. — это совсем другая тема и философия проектирования. Но мы сейчас не об этом.
Существует несколько подходов к реализации таких объектов. Я предлагаю один из них, которым пользуюсь уже на протяжении многих лет.
//-------------------------------------------------------------------------- // File: a_singleton.h // // Desc: An one-instance class //-------------------------------------------------------------------------- #ifndef A_SINGLETON_H #define A_SINGLETON_H #include <QtGlobal> // disable the warning regarding 'this' pointers being used in // base member initializer list. Singletons rely on this action #pragma warning(disable : 4355) //-------------------------------------------------------------------------- // Name: uSingleton // Desc: A singleton is a type of class of which only one instance may // exist. This is commonly used for management classes used to // control system-wide resources. //-------------------------------------------------------------------------- template <class T> class uSingleton { public: // the singleton must be constructed with a reference to the controlled object //---------------------------------------------------------------------- uSingleton(T& rObject) { Q_ASSERT_X(!s_pInstance, "constructor", "Only one instance of this class is permitted."); s_pInstance = &rObject; } // the singleton accessor //---------------------------------------------------------------------- ~uSingleton() { Q_ASSERT_X(s_pInstance, "destructor", "The singleton instance is invalid."); s_pInstance = 0; } // the singleton accessor //---------------------------------------------------------------------- static T& instance() { Q_ASSERT_X(s_pInstance, "instancing", "The singleton has not yet been created."); return (*s_pInstance); } private: // Data... //---------------------------------------------------------------------- static T* s_pInstance; // Nonexistant Functions... //---------------------------------------------------------------------- uSingleton(const uSingleton& Src); uSingleton& operator=(const uSingleton& Src); }; template <class T> T* uSingleton<T>::s_pInstance = 0; #endif // A_SINGLETON_H
Объявление класса:
//-------------------------------------------------------------------------- // File: usingletonuserclass.h //-------------------------------------------------------------------------- #ifndef USINGLETONUSERCLASS_H #define USINGLETONUSERCLASS_H #include <QObject> #include "a_singleton.h" // Defines for geting instance class MyClass; #define MY_CLASS MyClass::instance() //-------------------------------------------------------------------------- // Name: MyClass //-------------------------------------------------------------------------- class MyClass : public QObject, public uSingleton<MyClass> { Q_OBJECT public: explicit MyClass(QObject* parent = 0); // Test function to show work with singleton void testFunc() {}; }; #endif // USINGLETONUSERCLASS_H
Не забудьте инициализировать синглетон в конструкторе:
//-------------------------------------------------------------------------- // MyClass singleton constructor //-------------------------------------------------------------------------- MyClass::MyClass(QObject *parent) : QObject(parent), uSingleton<MyClass>(*this) { /* ... */ }
Теперь доступ к объекту класса производится простым и понятным путем:
// ... MY_CLASS.testFunc(); // ...
Учим Яндекс индексировать сайт «без www»
Прошло уже почти два месяца, а Яндекс так и не проиндексировал уфна.ру. Точнее — не проиндексировал основной блог — старый сайт с хтмл’ными статьями он давно занес себе в память.
Я заинтересовался данным вопросом и пришел к выводу, что дело именно в определении зеркала сайта.
Для Яндекса дополнительно необходимо определить какое зеркало сайта является главным, с помощью директивы ‘Host‘ в файле robots.txt (Напомню — файл, находящийся в корневой директории сайта и задающий настройки для поисковых роботов). Код добавляемый в Robots.txt должен выглядеть следующим образом:
Кстати, «по хорошему» следует вынести директиву ‘Host‘ в отдельную секцию, предназначенную только для робота Яндекса (User-agent: Yandex), т.к. возможно, что другие поисковики (тот же Google, он чет странно разделил у меня сайт на два зеркала) могут некорректно отработать непонятную им директиву. Так же по стандартам файла robots.txt в каждой секции ‘User-agent‘ должна присутствовать хотя бы одна директива ‘Disallow‘, поэтому мы поставим в коде пустую, ничего не запрещающую директиву Disallow:. Тогда файл robots.txt, после добавления приведенного выше кода, будет выглядеть так:
Ну что ж, теперь ждем робота в гости :)