简体   繁体   English

C ++单例延迟初始化实现和链接似乎冲突

[英]C++ singleton lazy initialization implementation and linkage seems conflict

C++ Singleton design pattern I come across this question and learned that there are two ways to implement the singleton pattern in c++. C ++ Singleton设计模式我遇到了这个问题,并了解到有两种方法可以在c ++中实现Singleton模式。

1) allocate the single instance in heap and return it in the instance() call 1)在堆中分配单个实例,并在instance()调用中返回

2) return a static instance in the instance() call, this is also known as the lazy initialization implementation. 2)在instance()调用中返回静态实例,这也称为延迟初始化实现。

But I think the second, that is the lazy initialization implementation, is wrong due to following reasons. 但是我认为第二种方法,即延迟初始化实现,由于以下原因是错误的。 Static object returned from the instance() call has internal linkage and will have unique copies in different translation unit. 从instance()调用返回的静态对象具有内部链接,并且将在不同的转换单元中具有唯一的副本。 So if user modifies the singleton, it will not be reflected in any other translation unit. 因此,如果用户修改单例,它将不会反映在任何其他翻译单元中。

But there are many statement that the second implementation is correct, am I missing something? 但是有很多说法表明第二种实现是正确的,我是否缺少某些东西?

In the context of a method, the static keyword is not about linkage. 在方法的上下文中, static关键字与链接无关。 It just affects the "storage class" of the defined variable. 它只影响已定义变量的“存储类”。 And for static local variables the standard explicitly states: 对于静态局部变量,标准明确规定:

9.3.6 A static local variable in a member function always refers to the same object, whether or not the member function is inline. 9.3.6成员函数中的静态局部变量始终引用同一对象,无论成员函数是否为内联。

So it doesn't matter at all whether you put the code in a header or cpp file. 因此,将代码放在头文件还是cpp文件中都没有关系。

Note that for free / non-member function it does indeed depend on the linkage of the function, as KerrekSB pointed out. 请注意,正如KerrekSB所指出的那样,对于自由/非成员函数,它确实取决于函数的链接。

The linkage of the name of implementation object does not matter. 实现对象名称的链接无关紧要。 What matters is the linkage of the name of the function you use to access the object, and that name has, of course, external linkage: 重要的是你用来访问对象的函数的名称的联动, 这个名字有当然,外部链接的,:

thing.h: something.h:

Thing & TheThing();   // external linkage

thing.cpp: something.cpp:

#include "thing.h"

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

Every use of the name TheThing in the program refers to the same entity, namely the function defined (uniquely) in thing.cpp. 程序中对名称TheThing每次使用都指向同一个实体,即thing.cpp中(唯一)定义的函数。

Remember, linkage is a property of names , not of objects. 请记住,链接是名称的属性,而不是对象的属性。

You are wrong, because the singleton is defined in one single translation unit, the one that contains the definition of the function that returns it. 您错了,因为单例是在一个转换单元中定义的,该转换单元包含返回它的函数的定义。 That means that all translation units that wants to use the singleton ask it to the single one that actually defines it, and in the end all use the same object (as expected for a singleton pattern :-) ). 这意味着所有想要使用单例的翻译单元都将其询问给实际定义它的单个单元,最后所有单元都使用相同的对象(如单例模式所期望的那样:-)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM