访问共享库中定义的单例

Ill*_*kyy 5 c++ singleton shared-libraries

让我们假设我有以下架构:

  • Dodo 单身课程 libdodo
  • 主要方案有联系libdodolibponny; 主程序称为Dodo::instance()
  • Ponny来自libponny创建的类.它有Dodo单身标题

mainwindow.cpp

    #include "shared/dodo/dodo.h"
    // ...
    Dodo::instance()->setNumber(91);
Run Code Online (Sandbox Code Playgroud)

然后,在此调用之后,Ponny创建类(ponny.cpp)

ponny.cpp

    #include "shared/dodo/dodo.h"
    // ...
    bool is = (Dodo::instance()->number() == 91);
    // Will `is` be true?
Run Code Online (Sandbox Code Playgroud)

那么,我可以这样做吗?

Lih*_*ihO 4

由于单例的行为定义位于其库中,这意味着单例实例将是唯一的,并且它将存在于创建它的编译单元中。

\n\n

假设有libdodoDodo.cpp其中有:

\n\n
static Dodo& Dodo::instance()\n{\n    static Dodo dodo;\n    return dodo;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,局部静态变量在第一次执行到达其声明时被初始化,因此在这种情况下,当Dodo::instance第一次被调用时,因此很可能您不会遇到像这样的单例的延迟初始化的任何问题。

\n\n

这里起作用的唯一事实是线程安全,因为当更多线程Dodo::instance()第一次调用时可能会出现竞争条件。有关更多信息,我建议您阅读:
\n这个问题:单例和多线程
\n这篇文章:C++ 作用域静态初始化不是线程安全的,是故意的!
\n这个问题也可以帮助你: Thread safe lazy Construction of a singleton in C++

\n\n
\n\n

另请注意,在 C++11 (\xc2\xa76.7.4) 中,静态变量的初始化保证是线程安全的:

\n\n
\n

如果在初始化变量时控制同时进入声明,则并发执行应等待初始化完成。

\n
\n\n

这意味着像这样的惰性初始化变得有点防弹;)

\n