Cor*_*uzu 4 c++ singleton design-patterns
我正在开发一个C++项目,它有多个必须是单例的类,它们之间存在依赖关系(初始化顺序很重要).
我想出了这个解决方案:
Run Code Online (Sandbox Code Playgroud)class MySingleton1 { protected: MySingleton1(); }
Run Code Online (Sandbox Code Playgroud)#include "MySingleton1.hpp" #include "MySingleton2.hpp" class Singletons : public MySingleton1, public MySingleton2 {} static Singletons s_singletons;
Run Code Online (Sandbox Code Playgroud)template<> MySingleton1& getSingleton() { return s_singletons; } template<> MySingleton2& getSingleton() { return s_singletons; }
Run Code Online (Sandbox Code Playgroud)template <class TSingleton> TSingleton& getSingleton();
好处:
低耦合:
可以通过改变 Singletons类的继承顺序来控制初始化顺序
缺点:
所以,据我所知,这实际上是相当不错的,所以我想这样离开它,但我要求你的反馈(比编程社区更好的地方呢?).
您对此解决方案有什么额外的优势/劣势?
你有什么选择吗?
这迫使Singletons集中化,这可能会破坏更复杂项目中的依赖关系.singleton.cpp必须依赖于每个单身人士所需的一切的图书馆.同时,使用单身人士的任何人都必须依赖于singleton.cpp图书馆.
基本上,您的代码只能在单片非模块化项目中工作.将其扩展到多个动态库几乎是不可能的.
您的初始化顺序必须手动维护.
静态全局变量的构造点在第一个表达式之前的所有内容都没有排序main.
我用过的一个不错的解决方案是创建一个包含单例内存的动态库.
要成为单例,您从CRTP助手继承,它提供::Instance()内联方法.人们想要使用单身人士::Instance().
::Instance()创建静态局部变量生命周期令牌.然后它尝试从主DLL获取单例的存储空间; 如果已经创建了对象,它只是将存储转换为对象类型,并增加其引用计数.
如果没有,它会创建新存储并在其中构造对象.
在破坏静态局部变量生命周期令牌时,它会减少引用计数.如果该引用计数达到0,则会在当前动态库中本地销毁它.
单例的生命周期现在是::Instance()创建变量的生命周期的并集.破坏发生在非类型擦除的代码中,因此我们不必担心卸载代码的DLL.存储是核心.存储存储的DLL必须低于Singleton系统的每个用户,但它反过来没有依赖关系,所以这不是一个痛苦.
这远非完美; 单身人士和一生都是一个长期存在的问题,因为单身人士的存在使得干净的程序关闭变得困难并且变得更加困难.但它迄今为止在一个相当大的项目中工作.