C ++单例代码的解释

时间:2013-10-08 02:11:28

标签: c++ class design-patterns static singleton

我最近被问到c ++中的单例设计模式。我不确切知道它的作用或何时需要,所以我试着用谷歌搜索它。我发现很多答案主要是在stackoverlow上,但我很难理解这些问题和答案中提到的代码。我知道单身人士应该满足以下属性,如果我错了,请纠正我。

It is used when we need to make one and only one instance of a class. 

这在我的脑海中提出了以下问题

Does this mean that it can be created only once or does this mean that it can be 
created many times but at a time only one copy can exist?

现在开始实施。     从here

复制
class S
{
    public:
        static S& getInstance()
        {
            static S    instance; // Guaranteed to be destroyed.
                              // Instantiated on first use.
            return instance;
        }
    private:
        S() {};                   // Constructor? (the {} brackets) are needed here.
        // Don't forget to declare these two. You want to make sure they
        // are inaccessible otherwise you may accidentally get copies of
        // your singleton appearing.
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement
};

请解释:

  1. 为什么我们必须使getinstace()函数静态?
  2. 为什么我们需要S(S const&);构造
  3. void operator =(S const&);办?
  4. 为什么我们不实现最后两个功能?
  5. 为什么我们需要保证销毁此实例(如代码中所述)?

3 个答案:

答案 0 :(得分:3)

  

1.为什么我们必须使getinstace()函数保持静态?

这是获取实例的唯一方法 - 静态意味着您不需要现有实例来调用它。如果你需要一个实例来获取一个实例,那么你将陷入鸡与蛋的关系。

那是因为它可以写静态:

S::getinstance().blah();

如果它不是静态的,你需要写

S& s_instance = .... 
s_instance.getInstance().blah();

但是因为你已经有了一个实例,所以你不需要拨打getInstance。如果获取实例的唯一方法是通过getInstance

,那么如何获得该实例?
  

2.为什么我们需要S(S const&);构造吗

你没有。它故意私有而未实现,因此调用它将导致错误。 如果它没有明确地变为私有而没有实现,编译器将为你创建一个默认的公共拷贝构造函数......这意味着人们可以写

S scopy(S::getInstance());

他们最终会得到一个新的S - 破坏单例语义的实例。

  

3. void operator =(S const&);做吗

相同2.它没有实现和私有,所以调用它将导致错误。如果你没有明确说明,编译器会为你创建一个默认的,在这种情况下,用户可以通过它获得一个新实例。

S scopy = S::getInstance();
  

4.为什么我们不实施最后两个功能?

如果您可以复制/分配单身,它将失去其单身人士身份。任何时候都只能存在一个单身人士。

但请注意,单例通常被视为反模式。没有非常充分理由你不想使用的东西。理解随之而来的线程问题也是明智的......然后最重要的是,你会遇到一些实现它的静态初始化命令惨败。 (代码中的方式没问题,但很容易出错。)

答案 1 :(得分:1)

1)是的。此功能可让您实际获得S的单个实例。所以你打电话给S::getInstance()。如果它不是静态的那么你将无法做到这一点。

2,3和4)请注意,构造函数和operator=是私有的。这是为了防止某人制作S的另一个实例,从而使单身人士状态无效。

您应该使用S来获取单个实例,而不是构建自己的S::getInstance()

答案 2 :(得分:1)

  1. 是的,它应该是静态的,因为它不需要实例指针。使其成为非静态的将是徒劳的。

  2. 是的,我们至少需要一个功能构造函数。初始实例需要以某种方式进行。创建第一个实例时,私有构造函数将强制外部用户通过getInstance获取实例。

  3. 当您为此实例分配新值时,将使用赋值运算符operator=(S const&)。对于单例是没有意义的,因此被声明为私有而没有实现。没有人可以使用它。

  4. 不,复制构造函数和赋值运算符必须是私有的,没有实现。这是一个C ++习语,意思是:此类不能复制,也不能分配给