Можно ли наследовать одноэлементный класс. Если да, то как мы можем это сделать?
** EDIT: *** Я хочу сказать, что если у нас есть класс, который использует шаблон дизайна singleton, то может ли он быть унаследован? *
Можно ли наследовать одноэлементный класс. Если да, то как мы можем это сделать?
** EDIT: *** Я хочу сказать, что если у нас есть класс, который использует шаблон дизайна singleton, то может ли он быть унаследован? *
singleton имеет частный конструктор, поэтому наследование невозможно. кроме того, у singleton есть статические методы для создания экземпляра частного экземпляра, и поскольку вы не можете переопределять статические методы, было бы бессмысленно наследовать от singleton.
Это зависит от того, как ваша реализация для шаблона проектирования. Простейшей формой является создание такого класса:
class MySingleton
{
public:
static MySingleton &getInstance()
{
static MySingleton instance;
return instance;
}
private:
MySingleton();
~MySingleton();
};
В этом случае он не может быть унаследован, потому что производный класс не имеет доступа к его конструктору. Вы можете сделать конструктор защищенным, но это позволит другим производным классам быть не одиночными по желанию, что может быть беспорядочным с точки зрения дизайна. Но обычно эта простая форма не является предпочтительным способом реализации синглетонов, так как у вас нет большого контроля над ее временем жизни, и трудно правильно обрабатывать зависимости между синглтонами - не говоря уже о возможных проблемах многопоточности. Книга Современный дизайн на С++ (http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315/ref = sr_1_1? Ie = UTF8 & s = books & qid = 1270652521), среди прочих, имеет лучшие реализации; они основаны на шаблонах, а создание экземпляра шаблона делает объект одиночным (и его параметр является классом, который будет сделан одиночным). Это облегчает выполнение того, что вы хотите, поскольку "singleton-ness" отделен от самого класса. Но, тем не менее, я думаю, вам понадобится некоторая политика (возможно, введенная в действие кодом), чтобы избежать того, что какой-то класс, полученный из одноэлементного, будет не одиночным, что трудно реализовать.
Моя рекомендация состояла бы в том, чтобы иметь абстрактные базовые классы в качестве предков для ваших синглтонов и вносить в них поведение commom, а не в одиночном одиночном режиме, и иметь singleton всегда как "конечный" класс (заимствуя это значение из Java).
Синглтонные классы должны быть унаследованы. Шаблон singleton не имеет большого значения без наследования.
instance().instance(), чтобы решить во время выполнения, какой класс должен быть создан и возвращен.У меня есть класс Singleton, который я наследую во многих случаях.
Вот Синглтон:
template <class Target>
class Singleton_Shared_Ptr
{
//---------------------------------------------------------------------
// Public Constructors & Destructors
//---------------------------------------------------------------------
public:
//! Destructor.
virtual ~Singleton_Shared_Ptr();
//---------------------------------------------------------------------
// Public methods
//---------------------------------------------------------------------
public:
//! Returns a pointer to the instance.
static boost::shared_ptr<Target> ptr(void);
//! Returns a reference to the instance.
static Target & ref(void);
//---------------------------------------------------------------------
// Protected methods
//---------------------------------------------------------------------
protected:
//! Default constructor.
Singleton_Shared_Ptr();
//---------------------------------------------------------------------
// Private methods
//---------------------------------------------------------------------
private:
//! Copy constructor, not implemented.
/*! The copy constructor is declared so that the compiler will not
* automatically generate one.
*/
Singleton_Shared_Ptr(const Singleton_Shared_Ptr& s);
//! Assignment operator, declared but not defined.
/*! The assignment operator is declared so that the compiler will not
* automatically generate one.
*/
Singleton_Shared_Ptr& operator=(const Singleton_Shared_Ptr& s);
//---------------------------------------------------------------------
// Private members
//---------------------------------------------------------------------
private:
static wxMutex m_instance_mutex;
};
template<class Target>
wxMutex Singleton_Shared_Ptr<Target>::m_instance_mutex;
//-------------------------------------------------------------------------
// Singleton_Shared_Ptr Constructors & Destructors
//-------------------------------------------------------------------------
template <class Target>
inline
Singleton_Shared_Ptr<Target> ::
Singleton_Shared_Ptr()
{
}
template <class Target>
inline
Singleton_Shared_Ptr<Target> ::
~Singleton_Shared_Ptr()
{
}
//-------------------------------------------------------------------------
// Singleton_Shared_Ptr methods in alphabetical order
//-------------------------------------------------------------------------
template <class Target>
boost::shared_ptr<Target>
Singleton_Shared_Ptr<Target> ::
ptr(void)
{
static boost::shared_ptr<Target> p_instance;
if (p_instance.get() == NULL)
{
wxMutexLocker lock(m_instance_mutex);
if (!p_instance)
{
p_instance.reset(new Target);
}
}
return p_instance;
}
template <class Target>
Target &
Singleton_Shared_Ptr<Target> ::
ref(void)
{
return *(ptr());
}
Вот использование singleton:
class Manager
: public Singleton_Shared_Ptr<Manager>
{
//---------------------------------------------------------------------
// Friends
//---------------------------------------------------------------------
friend class Common::Singleton_Shared_Ptr<Manager>;
//---------------------------------------------------------------------
// Public Constructors and Destructors
//---------------------------------------------------------------------
public:
//! destructor
virtual ~Manager();
//---------------------------------------------------------------------
// Protected Methods
//---------------------------------------------------------------------
protected:
//! Constructor
Manager();
//! Copy constructor -- declared but not implemented.
Manager(const Manager& m);
//! Assignment operator -- declared but not implemented.
Manager& operator= (const Manager& m);
};