C++-单例模式类

3

一个单例类可以被继承吗? 如果可以, 那么如何实现?

**编辑:***我是想说,如果我们有一个使用单例设计模式的类,它可以被继承吗?*


6
是的。类A : 公共单例{ ... }; - anon
3
我认为尼尔的意思是我们需要更多信息。大致上是“我有一个单例,长这样……我想要继承它以使它能够做到以下……” - tloach
1
没有“the” Singleton 可以询问问题,这取决于您对模式的实现。如果您甚至需要该模式。(提示:您不需要)。http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-since-1995/ - GManNickG
4个回答

4

单例模式有私有构造函数,因此不能继承。此外,单例模式具有静态方法来实例化私有实例成员,由于无法覆盖静态方法,因此从单例继承将毫无意义。


单例通常有一个受保护的构造函数。 - Marcelo Cantos
4
我们没有相同的单例对象。如果被保护起来,就无法保证唯一性。 - Matthieu M.
@Marcelo:我、Matthieu和其他人所称的“singleton”是指只有一个实例的类,而你所称的“Singleton”是具有单例支持代码的抽象基类。我认为更适合称其为“SingletonBase”,因为该类本身并不是单例——单例是具体的类。 - Fabio Ceconello
顺便提一下,Alexandrescu 将其实现为模板,而不是基类,并因此将其命名为“SingletonHolder”。 - Fabio Ceconello

3

这取决于你对设计模式的实现方式。最简单的形式是创建一个像这样的类:

class MySingleton
{
    public:
        static MySingleton &getInstance()
        {
            static MySingleton instance;            
            return instance;
        }
    private:
        MySingleton();
        ~MySingleton();
};

在这种情况下,它无法被继承,因为派生类无法访问其构造函数。您可以将构造函数设置为受保护,但这将使其他派生类随意成为非单例模式,从设计角度来看可能会很混乱。但通常,这种简单形式不是实现单例模式的首选方式,因为您对其生命周期没有太多控制,并且很难正确处理单例之间的依赖关系 - 更不用提可能的多线程问题了。书籍《现代C++设计》(http://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315/ref=sr_1_1?ie=UTF8&s=books&qid=1270652521)等有更好的实现方法;它们是基于模板的,模板实例化是使对象成为单例的原因(其参数是将成为单例的类)。这样做可以更容易地实现您想要的功能,因为“单例性”与类本身分离。但尽管如此,我认为您需要一些策略(可能由代码强制执行),以避免某个派生自单例的类成为非单例,这很难实现。
我的建议是将抽象基类作为单例的祖先,并将通用行为放在它们中,而不是放在单例本身中,并始终将单例作为“final”类(从Java借用这个意义)。

这个链接也非常有帮助:http://www.yolinux.com/TUTORIALS/C++Singleton.html - jhtong

1

单例模式类是为了被继承而设计的。如果没有继承,单例模式就没有什么价值。

  1. 定义一个大部分是抽象的基类,并有一个静态的 instance() 成员函数。
  2. 定义一个或多个派生类来实现基类接口。
  3. 实现 instance() 函数,在运行时决定实例化和返回哪个类。

4
我的单例模式没有继承,但它们似乎非常有用。不要将模式与实现混淆。 - anon
有些人会说,你所描述的实际上是Singleton和Factory的组合,而不仅仅是Singleton。但我同意,没有Factory的Singleton通常是反模式。 - Kristopher Johnson
我同意Kristopher的观点。从技术上讲,这并不是单例模式。但是,这就是我的做法,因为如果没有在不同情况下(每个应用程序上下文[应用程序/测试等])实例化(或注册)不同的单例,那么测试系统将变得不可能(或非常困难)。 - Martin York
如果你阅读了GoF关于这个模式的论述,继承被指出是一个非常重要的动机。很难说他们是否认为它是一个先决条件,但我一直把它看作是这样的。 - Marcelo Cantos

0

我有一个单例类,我在许多实例中继承它。

以下是该单例类:

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());
}

这里是单例模式的用法:

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);
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接