作为静电字段的单个实例与getInstance()方法中的静电变量

在this thread中,关于单例实例的描述如下:

静电变量可以是getInstance()函数的静电,也可以是Singleton类中的静电。这里有一些有趣的权衡。

这些权衡是什么?我知道,如果声明为static函数变量,则在第一次调用函数之前不会构造单例。我也读过一些关于线程安全的文章,但我不知道这到底需要什么,也不知道这两种方法在这方面有什么不同。

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

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

附录:重载operator()为单例调用createItem()方法,以便可以这样创建Item,这个想法有多好:ItemFactory::factory("id")


解决方案

这些权衡是什么?

这是最重要的注意事项:

static数据成员在程序开始时的静电初始化过程中初始化。如果任何static对象依赖于单例,则将存在一个static initialization order fiasco。

函数LOCALstatic对象在第一次调用函数时初始化。因为任何依赖单例的人都会调用该函数,所以单例将被适当地初始化,并且不会受到失败的影响。破坏仍然存在一个非常微妙的问题。如果静电对象的析构函数依赖于单例,而该对象的构造函数不依赖于单例,那么您将得到未定义的行为。

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

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

哪种方法更好?

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

相关文章