c++ - 单例实例作为静态字段与 getInstance() 方法中的静态变量

标签 c++ design-patterns singleton c++14 static-members

this thread , 以下是关于单例实例的说明:

The static variable can be static to the GetInstance() function, or it can be static in the Singleton class. There's interesting tradeoffs there.

这些权衡是什么?我知道,如果声明为 static 函数变量,则在首次调用该函数之前不会构造单例。我也读过一些关于线程安全的内容,但我不知道这到底意味着什么,或者这两种方法在这方面有何不同。

两者之间还有其他主要区别吗?哪种方法更好?

在我的具体示例中,我将工厂类设置为单例,并将实例存储为类中的 static const 字段。我没有 getInstance() 方法,而是希望用户直接访问实例,如下所示:ItemFactory::factory。默认构造函数是私有(private)的,实例是静态分配的。

附录:重载 operator() 以调用单例的 createItem() 方法是多么好的想法,这样 Item 可以像这样创建:ItemFactory::factory("id")?

最佳答案

What are these trade-offs?

这是最重要的考虑因素:

static 数据成员在程序开始时的静态初始化期间被初始化。如果任何 static 对象依赖于单例,那么就会有一个 static initialization order fiasco .

函数局部static对象在第一次调用函数时被初始化。由于依赖于单例的任何人都会调用该函数,因此单例将被适本地初始化并且不易受到惨败的影响。销毁仍然存在一个非常微妙的问题。如果静态对象的析构函数依赖于单例,但该对象的构造函数不依赖,那么您最终会遇到未定义的行为。

此外,在第一次调用函数时进行初始化,意味着可以在完成静态初始化并调用 main 之后调用该函数。因此,程序可能产生了多个线程。 static 本地的初始化可能存在竞争条件,导致构造多个实例。幸运的是,自 C++11 起,该标准保证初始化是线程安全的,并且这种权衡不再存在于符合规范的编译器中。

线程安全不是static 数据成员的问题。

Which approach is better?

这取决于您的要求以及您支持的标准版本。

关于c++ - 单例实例作为静态字段与 getInstance() 方法中的静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34396373/

相关文章:

android - 使用 linkify 创建链接

c++ - 帮我去掉一个Singleton : looking for an alternative

c++ - EOF 的功能问题

c++ - 'new' 和 'delete' 在 C++ 中被弃用了吗?

javascript - 这个命名的自调用函数如何传递参数?

java - 模型是否应该调用服务来获取数据

c++ - 如何避免在基于 REST API 的游戏中使用单例模式?

java - Java中静态字段什么时候初始化?

C++ 默认参数 - 声明

c++ - 通过 boost lambda 占位符访问成员变量