C ++ singleton lazy初始化实现和链接似乎冲突

时间:2017-02-25 14:20:23

标签: c++ singleton linkage

C++ Singleton design pattern我遇到了这个问题,并了解到有两种方法可以在c ++中实现单例模式。

1)在堆中分配单个实例并在instance()调用中返回它

2)在instance()调用中返回一个静态实例,这也称为延迟初始化实现。

但我认为第二个,即延迟初始化实现,由于以下原因是错误的。 从instance()调用返回的静态对象具有内部链接,并且将在不同的翻译单元中具有唯一副本。因此,如果用户修改单例,它将不会反映在任何其他翻译单元中。

但有很多声明说第二次实施是正确的,我错过了什么吗?

3 个答案:

答案 0 :(得分:3)

在方法的上下文中,static关键字与链接无关。它只影响"存储类"定义的变量。对于静态局部变量,标准明确指出:

  

9.3.6成员函数中的静态局部变量总是引用同一个对象,无论成员函数是否为内联函数。

因此,将代码放在标头或cpp文件中根本不重要。

请注意,对于自由/非成员函数,它确实依赖于函数的链接,正如KerrekSB指出的那样。

答案 1 :(得分:1)

实现对象名称的链接无关紧要。重要的是用于访问对象的函数名称的链接,以及 名称当然具有外部链接:

<强> thing.h:

Thing & TheThing();   // external linkage

<强> thing.cpp:

#include "thing.h"

Thing & TheThing() { static Thing impl; return impl; }

程序中名称TheThing的每次使用都指向同一个实体,即thing.cpp中定义的(唯一)函数。

请记住,链接是 names 的属性,而不是对象的属性。

答案 2 :(得分:-1)

你错了,因为单例是在一个单独的翻译单元中定义的,它包含返回它的函数的定义。这意味着所有想要使用单例的翻译单元都要求它实际定义它的单个翻译单元,最后所有翻译单元都使用相同的对象(正如 singleton 模式所预期的那样:-))