Meyers单例和动态库

一台电视

Meyers Singleton是否可以在带有动态库的场景中使用?
是一个库定义单例,其他库使用单例库,每个库都在自己的编译单元中?
我想没关系,但是特定的体系结构是在OS X上带有框架的应用程序

我使用的是香草Meyers Singleton模式:Instance()在实用程序类(在动态库中定义)的头文件中内联定义以下方法:

    static Logger&  Instance()
              {
                 static Logger singletonInstance;
                 return singletonInstance;
              }

复制构造函数并operator=声明为私有且未实现,所以我们应该很好,对吧?

现在,如果我从主应用程序链接定义单例的库,则可以看到该构造函数被多次调用..具有不同的地址,this并且在没有实际单例但有多个类实例的情况下,我会期望所有的怪异。

因此,我想知道动态库方法是不是搞砸了Meyers单例,还是包括单例头的每个编译单元(库,主应用)(有效地声明和定义Instance()方法)是否会得到“它是自己的单例”实例“?

真的不太确定如何处理我的观察结果,因此非常感谢任何提示!

霍华德·辛南特

您需要在标头中声明 Instance,然后在动态库中定义它(可能与其中Logger定义的相同)。而且您需要删除staticInstance如果使用可见性工具,需要确保具有默认可见

从您的描述中,听起来好像您已在标头中定义了此函数。这将使每个包含标头的人都有他们自己的私有定义Instance,从而使他们自己对static Logger内部的私有定义Instance

您可以声明Instance inline,这将为您提供所有期望的语义(与在标头中声明和在dylib中定义相同)。但是我的建议是直接进行内联以确认我所告诉的内容是正确的(这很容易),然后勾勒出一个dylib(并再次确认)。

概述后,您的设计应该可以正常工作。

话虽如此,它只能保证在C ++ 11中工作。也就是说,局部静态变量在C ++ 98/03中不是线程安全的,但在C ++ 11及更高版本中才是线程安全的。但是,在OS X上,即使在C ++ 03语言模式下作为扩展,它们也是线程安全的。

另外一个警告:如果您访问Instance()中的atexit链(或全局对象的析构函数),即静态局部破坏后会发生您的访问有可能singletonInstanceInstance(),导致未定义的行为。如果您没有使用进行注册atexit(),并且您的全局析构函数没有调用Instance(),那么您会很安全。否则你不是。如果您不安全,则可以有目的地泄漏它:

Logger&  Instance()
{
   static Logger* singletonInstance = new Logger;
   return *singletonInstance;
}

这可能会导致某些内存泄漏检查程序报告误报(或者,根据您的观点,它们可能是真正的肯定),这很令人讨厌。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章