• <tfoot id='OKQn1'></tfoot>

      <legend id='OKQn1'><style id='OKQn1'><dir id='OKQn1'><q id='OKQn1'></q></dir></style></legend>

          <bdo id='OKQn1'></bdo><ul id='OKQn1'></ul>

      1. <i id='OKQn1'><tr id='OKQn1'><dt id='OKQn1'><q id='OKQn1'><span id='OKQn1'><b id='OKQn1'><form id='OKQn1'><ins id='OKQn1'></ins><ul id='OKQn1'></ul><sub id='OKQn1'></sub></form><legend id='OKQn1'></legend><bdo id='OKQn1'><pre id='OKQn1'><center id='OKQn1'></center></pre></bdo></b><th id='OKQn1'></th></span></q></dt></tr></i><div id='OKQn1'><tfoot id='OKQn1'></tfoot><dl id='OKQn1'><fieldset id='OKQn1'></fieldset></dl></div>
      2. <small id='OKQn1'></small><noframes id='OKQn1'>

        迈耶斯对单例的实现如何实际上是单例

        时间:2023-10-07

                <bdo id='6kWRK'></bdo><ul id='6kWRK'></ul>
                <tfoot id='6kWRK'></tfoot>
                <i id='6kWRK'><tr id='6kWRK'><dt id='6kWRK'><q id='6kWRK'><span id='6kWRK'><b id='6kWRK'><form id='6kWRK'><ins id='6kWRK'></ins><ul id='6kWRK'></ul><sub id='6kWRK'></sub></form><legend id='6kWRK'></legend><bdo id='6kWRK'><pre id='6kWRK'><center id='6kWRK'></center></pre></bdo></b><th id='6kWRK'></th></span></q></dt></tr></i><div id='6kWRK'><tfoot id='6kWRK'></tfoot><dl id='6kWRK'><fieldset id='6kWRK'></fieldset></dl></div>

                <small id='6kWRK'></small><noframes id='6kWRK'>

                  <tbody id='6kWRK'></tbody>

                • <legend id='6kWRK'><style id='6kWRK'><dir id='6kWRK'><q id='6kWRK'></q></dir></style></legend>
                • 本文介绍了迈耶斯对单例的实现如何实际上是单例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我已经阅读了很多关于单身人士,何时应该和不应该使用它们,以及如何安全地实现它们.我正在用 C++11 编写,并且遇到了 Meyer 对单例的惰性初始化实现,如 这个问题.

                  I have been reading a lot about Singletons, when they should and shouldn't be used, and how to implement them safely. I am writing in C++11, and have come across the Meyer's lazy initialized implementation of a singleton, as seen in this question.

                  这个实现是:

                  static Singleton& instance()
                  {
                       static Singleton s;
                       return s;
                  }
                  

                  我从 SO 上的其他问题中了解到这是线程安全的,但我不明白这实际上是一个单例模式.我已经用其他语言实现了单例,这些总是像来自 维基百科的这个例子一样结束:

                  I understand how this is thread safe from other questions here on SO, but what I don't understand is how this is actually a singleton pattern. I have implemented singletons in other languages, and these always end up something like this example from Wikipedia:

                  public class SingletonDemo {
                          private static volatile SingletonDemo instance = null;
                  
                          private SingletonDemo() {       }
                  
                          public static SingletonDemo getInstance() {
                                  if (instance == null) {
                                          synchronized (SingletonDemo .class){
                                                  if (instance == null) {
                                                          instance = new SingletonDemo ();
                                                  }
                                        }
                                  }
                                  return instance;
                          }
                  }
                  

                  当我查看第二个示例时,非常直观地看出这是一个单例,因为该类持有对自身的一个实例的引用,并且只返回该实例.但是,在第一个示例中,我不明白这如何防止对象的两个实例存在.所以我的问题是:

                  When I look at this second example, it is very intuitive how this is a singleton, since the class holds a reference to one instance of itself, and only ever returns that instance. However, in the first example, I don't understand how this prevents there ever existing two instances of the object. So my questions are:

                  1. 第一个实现如何强制执行单例模式?我认为这与 static 关键字有关,但我希望有人能向我深入解释幕后发生的事情.
                  2. 在这两种实现方式之间,一种优于另一种吗?利弊是什么?

                  感谢您的帮助,

                  推荐答案

                  这是一个单例,因为函数 local 的 static 存储持续时间意味着程序中只存在该 local 的一个实例.

                  This is a singleton because static storage duration for a function local means that only one instance of that local exists in the program.

                  在幕后,这可以粗略地认为等同于以下 C++98(甚至可能被编译器像这样模糊地实现):

                  Under the hood, this can very roughly be considered to be equivalent to the following C++98 (and might even be implemented vaguely like this by a compiler):

                  static bool __guard = false;
                  static char __storage[sizeof(Singleton)]; // also align it
                  
                  Singleton& Instance() {
                    if (!__guard ) {
                      __guard = true;
                      new (__storage) Singleton();
                    }
                    return *reinterpret_cast<Singleton*>(__storage);
                  }
                  
                  // called automatically when the process exits
                  void __destruct() {
                    if (__guard)
                      reinterpret_cast<Singleton*>(__storage)->~Singleton();
                  }
                  

                  线程安全位使它变得有点复杂,但本质上是一样的.

                  The thread safety bits make it get a bit more complicated, but it's essentially the same thing.

                  查看 C++11 的实际实现,每个静态(如上面的布尔值)都有一个保护变量,它也用于屏障和线程.查看 Clang 的 AMD64 输出:

                  Looking at an actual implementation for C++11, there is a guard variable for each static (like the boolean above), which is also used for barriers and threads. Look at Clang's AMD64 output for:

                  Singleton& instance() {
                     static Singleton instance;
                     return instance;
                  }
                  

                  instance 的 AMD64 程序集,来自 Ubuntu's Clang 3.0 on AMD64 at -O1(由 http://gcc 提供).Godbolt.org/ 是:

                  The AMD64 assembly for instance from Ubuntu's Clang 3.0 on AMD64 at -O1 (courtesy of http://gcc.godbolt.org/ is:

                  instance():                           # @instance()
                    pushq %rbp
                    movq  %rsp, %rbp
                    movb  guard variable for instance()::instance(%rip), %al
                    testb %al, %al
                    jne   .LBB0_3
                    movl  guard variable for instance()::instance, %edi
                    callq __cxa_guard_acquire
                    testl %eax, %eax
                    je    .LBB0_3
                    movl  instance()::instance, %edi
                    callq Singleton::Singleton()
                    movl  guard variable for instance()::instance, %edi
                    callq __cxa_guard_release
                  .LBB0_3:
                    movl  instance()::instance, %eax
                    popq  %rbp
                    ret
                  

                  可以看到它引用了一个全局守卫来查看是否需要初始化,使用__cxa_guard_acquire,再次测试初始化​​,等等.除了使用 AMD64 程序集和 中指定的符号/布局外,几乎所有方面都与您从维基百科发布的版本类似安腾 ABI.

                  You can see that it references a global guard to see if initialization is required, uses __cxa_guard_acquire, tests the initialization again, and so on. Exactly in almost every way like version you posted from Wikipedia, except using AMD64 assembly and the symbols/layout specified in the Itanium ABI.

                  请注意,如果您运行该测试,您应该为 Singleton 提供一个非平凡的构造函数,因此它不是 POD,否则优化器将意识到执行所有这些保护/锁定工作毫无意义.

                  Note that if you run that test you should give Singleton a non-trivial constructor so it's not a POD, otherwise the optimizer will realize that there's no point to doing all that guard/locking work.

                  这篇关于迈耶斯对单例的实现如何实际上是单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:如何在C++中正确实现工厂方法模式 下一篇:我们能否提高这种面向密钥的访问保护模式的可

                  相关文章

                  最新文章

                  <i id='HXRAU'><tr id='HXRAU'><dt id='HXRAU'><q id='HXRAU'><span id='HXRAU'><b id='HXRAU'><form id='HXRAU'><ins id='HXRAU'></ins><ul id='HXRAU'></ul><sub id='HXRAU'></sub></form><legend id='HXRAU'></legend><bdo id='HXRAU'><pre id='HXRAU'><center id='HXRAU'></center></pre></bdo></b><th id='HXRAU'></th></span></q></dt></tr></i><div id='HXRAU'><tfoot id='HXRAU'></tfoot><dl id='HXRAU'><fieldset id='HXRAU'></fieldset></dl></div>

                    <tfoot id='HXRAU'></tfoot>

                  1. <small id='HXRAU'></small><noframes id='HXRAU'>

                  2. <legend id='HXRAU'><style id='HXRAU'><dir id='HXRAU'><q id='HXRAU'></q></dir></style></legend>

                        <bdo id='HXRAU'></bdo><ul id='HXRAU'></ul>