关于C++中的两种单例模式
当我寻找有关 C++ 单例模式的信息时,我总是找到这样的例子:
class Singleton
{
public:
~Singleton() {
}
static Singleton* getInstance()
{
if(instance == NULL) {
instance = new Singleton();
}
return instance;
}
protected:
Singleton() {
}
private:
static Singleton* instance;
};
Singleton* Singleton::instance = NULL;
但是这种单例似乎也可以工作:
class Singleton
{
public:
~Singleton() {
}
static Singleton* getInstance()
{
return &instance;
}
protected:
Singleton() {
}
private:
static Singleton instance;
};
Singleton Singleton::instance;
我猜第二个单例是在程序开始时实例化的,与第一个不同,但这是唯一的区别吗?
为什么我们主要发现第一个?
When I look for informations about the singleton pattern for C++, I always find examples like this:
class Singleton
{
public:
~Singleton() {
}
static Singleton* getInstance()
{
if(instance == NULL) {
instance = new Singleton();
}
return instance;
}
protected:
Singleton() {
}
private:
static Singleton* instance;
};
Singleton* Singleton::instance = NULL;
But this kind of singleton also seems to work as well:
class Singleton
{
public:
~Singleton() {
}
static Singleton* getInstance()
{
return &instance;
}
protected:
Singleton() {
}
private:
static Singleton instance;
};
Singleton Singleton::instance;
I guess that the second singleton is instantiated at the beginning of the program, unlike the first, but is it the only difference?
Why do we find mainly the first?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
http://www.parashift.com/c++-faq-lite /ctors.html#faq-10.14
您列出的第一种方法完全避免了这个问题。这被称为“首次使用惯用法”
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
The first method you listed avoids this problem completely. It's called the "construct on first use idiom"
第一个允许您删除实例,而第二个则不允许。但请注意,您的第一个示例不是线程安全的
The first one allows you to delete the instance while the second one does not. But please be aware that your first example is not thread safe
它通常称为
static
初始化顺序惨败。总之,文件范围内的静态实例不一定在创建实例的显式函数调用之前初始化,如第一个示例中所示。It's commonly known as the
static
initialization order fiasco. In summary, static instances at file scope are not necessarily initialized before explicit function calls that create one as in your first example.单例模式通常被认为是不好的实践,因此经验证据(您“看到最多的”)在这种情况下没有什么价值。
第一个版本使用动态分配,而第二个版本使用静态分配。也就是说,第二次分配不能失败,而第一次分配可能会抛出异常。
这两个版本都有优点和缺点,但通常您应该尝试完全不需要单例的不同设计。
The singleton patterns is commonly considered Bad Practice, so empirical evidence (what you "see most") is of little value in this case.
The first version uses dynamic allocation, while the second one uses static allocation. That is, the second allocation cannot fail, while the first one could possibly throw an exception.
There are pros and cons to both versions, but generally you should try for a different design that doesn't require singletons at all.
第一个也是“惰性的”——只有在需要时才会创建它。如果您的
Singleton
很昂贵,这可能就是您想要的。如果您的
Singleton
很便宜并且您可以处理未定义的静态初始化顺序(并且您在 main() 之前不使用它),那么您不妨选择第二个解决方案。The first one is also "lazy" - it will be created only if and when it is needed. If your
Singleton
is expensive, this is probably what you want.If your
Singleton
is cheap and you can deal with undefined order of static initialization (and you don't use it before main()), you might as well go for the second solution.