[英]Explanation of C++ singleton code
最近有人问我有关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?
现在开始执行。 从这里复制
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()函数成为静态函数?
这是获取实例的唯一方法-静态意味着您不需要现有实例来调用它。 如果您需要一个实例来获取一个实例,那么您将陷入困境。
那是因为你可以写成静态的:
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)是的。 该函数实际上使您可以获取S
单个实例。 因此,您调用S::getInstance()
。 如果不是静态的,那么您将无法做到这一点。
2、3和4)请注意,构造函数和operator=
是私有的。 这是为了防止某人创建S
另一个实例,从而使单例状态无效。
与其构造自己的S
, S::getInstance()
使用S::getInstance()
获取单个实例。
是的,它应该是静态的,因为它不需要实例指针。 使其变为非静态将无济于事。
是的,我们确实需要至少一个函数构造函数。 初始实例需要以某种方式进行 。 创建第一个实例时,私有构造函数将强制外部用户通过getInstance
获取实例。
为该实例分配新值时,将使用赋值运算符operator=(S const&)
。 对于单例来说这没有任何意义,因此被声明为私有,并且没有实现。 没有人可以使用它。
不,复制构造函数和赋值运算符必须既是私有的,又没有实现。 这是C ++习惯用法,表示: 不能复制此类或将其分配给 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.