С++ - класс Singleton

Можно ли наследовать одноэлементный класс. Если да, то как мы можем это сделать?

** EDIT: *** Я хочу сказать, что если у нас есть класс, который использует шаблон дизайна singleton, то может ли он быть унаследован? *

Ответ 1

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

Ответ 2

Это зависит от того, как ваша реализация для шаблона проектирования. Простейшей формой является создание такого класса:

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).

Ответ 3

Синглтонные классы должны быть унаследованы. Шаблон singleton не имеет большого значения без наследования.

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

Ответ 4

У меня есть класс 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);
};