【问题标题】:C++-Singleton classC++-单例类
【发布时间】:2010-04-07 14:36:18
【问题描述】:

可以继承单例类。 如是, 那我们该怎么做呢?

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

【问题讨论】:

  • 是的。 A 类:公共单例 { ... };
  • 我认为 Neil 是想说我们需要更多信息。类似于“我有一个看起来像这样的单例......我想继承它以使其执行以下操作......”
  • 没有“the”Singleton 可以问问题,这取决于您对模式的实现。如果你甚至需要模式。 (提示:你没有)。 jalf.dk/blog/2010/03/…

标签: c++


【解决方案1】:

singleton 有私有构造函数,所以继承是不可能的。除了单例有静态方法来实例化私有实例成员,因为你不能覆盖静态方法,所以从单例继承是没有意义的。

【讨论】:

  • 单例通常有一个受保护的构造函数。
  • 那时我们没有相同的单例。如果受到保护,则无法保证唯一性。
  • @Marcelo:我、Matthieu 和其他人所称的“单例”是只有一个实例的类,而您称“单例”是具有单例支持代码的抽象基础。我认为将其称为“SingletonBase”会更合适,因为该类本身不是单例——单例是具体的类。
  • 顺便说一句,Alexandrescu 将其实现为模板,而不是基类,因此将其命名为“SingletonHolder”。
【解决方案2】:

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

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

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

我的建议是将抽象基类作为单例的祖先,并将通用行为放在其中,而不是单例本身,并且始终将单例作为“最终”类(从 Java 借用这个含义) .

【讨论】:

【解决方案3】:

单例类应该被继承。如果没有继承,单例模式就没有多大价值。

  1. 使用静态instance() 成员函数定义一个主要是抽象的基类。
  2. 定义一个或多个实现基接口的派生类。
  3. 实现instance() 以在运行时决定实例化和返回哪个类。

【讨论】:

  • 我的单身人士都没有被继承,但似乎非常有用。不要将模式与实现混淆。
  • 有人会说,你所描述的实际上是单例和工厂的组合,而不仅仅是单例。但我同意没有工厂的单例通常是一种反模式。
  • 我同意克里斯托弗的观点。这在技术上不是 Singelton 模式。但话说回来,这就是我这样做的方式,因为如果没有能力在不同的情况下(每个应用程序上下文 [app/test 等] 1 个)实例化(或注册)不同的单例,那么测试系统变得不可能(或非常困难)。
  • 如果您阅读了GoF's 对该模式的说明,继承被认为是最重要的动机。很难说他们是否认为这是一个先决条件,但我一直这样认为。
【解决方案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());
}

这里是单例的用法:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多