C ++ Singleton设计问题

时间:2010-08-26 18:16:19

标签: c++ constructor singleton

我要求在任何给定的时间点只有一个类的单个实例。单身人士是明显的候选人。 但我还有其他一些不典型的单身人士条件。

  1. 单身的生命周期不是程序的生命周期。每次进入特定状态时都必须创建此对象,并在离开状态时将其销毁。在状态的整个持续时间内,我无法创建该类的另一个实例。
  2. 每次,我进入状态并创建一个新实例,我需要将一个变量传递给单例。它是一个基于用户选择的数字。
  3. 所以我的实现有以下静态函数 -

    // To be called exactly once, everytime I enter the state
    void MySingleton::CreateInstance(size_t count);
    
    // To be called any no. of times during the state
    MySingleton * MySingleton::GetInstance();   
    
    // To be called exactly once, when leaving the state.
    void MySingleton::DestroyInstance();        
    

    现在,这种实现是传统单例实现的主要迂回。

    这种实施有问题吗?

    还有更好的选择吗?

6 个答案:

答案 0 :(得分:12)

如果每次进入给定状态时都创建一个实例,并在每次离开该状态时将其销毁,那么让实例归属于管理状态转换(或其他一些知道的实体)所有者更有意义国家转型)。

例如,您可以将一个指向实例的智能指针作为状态管理器的成员变量。当您转换到状态时,您可以将其初始化为新实例,当您转出状态时,您可以销毁该实例。

在我看来,这比使用单身设计(反)模式更清洁,更可取。

答案 1 :(得分:5)

  

这种实施有问题吗?

是的。问题是这不是Singleton ,因为它不是“Singleton”模式的全部内容。这是一个简单的变量,是你进入和离开的那个州的本地变量。

实际上,单身人士只是美化全球化,在整个应用程序的整个生命周期中都存活,无论如何都应该尽可能地防止。你的“单身人士”不是全球性的,而是一个地方性的。

答案 2 :(得分:2)

您所描述的概念可以通过以下类来确保:

template<class Guarded>
class single_instance : private boost::noncopyable {
   static bool alive;
public:
   single_instance() {
      if (alive)
         throw std::runtime_error("instance already exists");
      alive = true;
   }
   ~single_instance() {
      alive = false;
   }
};

template<class Guarded>
bool single_instance<Guarded>::alive = false;

如果您从中派生您的类,将确保您始终只能一次创建一个实例:

class myclass : single_instance<myclass> {
public:
   myclass(size_t count);
   ...
};

现在,您可以像普通类一样实现myclass,而无需工厂函数和getInstance方法。尝试在销毁第一个副本之前实例化第二个副本将引发异常。

答案 3 :(得分:1)

如果它是每个状态一个,那么从你的状态对象中创建它,并使构造函数为private,friend state。

答案 4 :(得分:1)

我完全同意“辛格尔顿只是另一种形式的全球化”,应该避免使用。

如果你的老板坚持,你可以尝试这样的事情:

class MyUtil
{
    protected:
    static MyUtil* m_Singleton = NULL;
    public:
    /// Create the singleton if does not exist.
    /// \return the singleton for this class.
    static GetSingleton()
    {
        if( !m_Singleton  )
        m_Singleton  = new MyUtil();
        return m_Singleton ;
    }

    /// release singleton instance
    /// Warning: Multi-threading not supported.
    void StateRelease()
    {
        m_Singleton  = NULL;
        delete this;
    }
};

答案 5 :(得分:0)

我认为这种解决方案的性能时间很长。我只创建一个实例,并将创建函数更改为:

void MySingleton::reset(size_t count);