Ben*_*ler 11 c++ singleton templates
在DLL中AI有一个模板单例:
template <class T>
class Singleton
{
public:
static T &instance()
{
static T _instance;
return _instance;
}
private:
//All constructors are here
};
Run Code Online (Sandbox Code Playgroud)
在Dll BI中定义一个类Logger.Dlls C,D和E使用Logger,它的访问方式如下:
Singleton<Logger>::instance();
Run Code Online (Sandbox Code Playgroud)
问题是每个dll都实例化它自己的副本
Singleton<Logger>.
Run Code Online (Sandbox Code Playgroud)
而不是使用相同的单例实例.我知道这个问题的解决方案是使用extern模板.这就是d,C,D和E必须包含的内容
extern template class Singleton<Logger>;
Run Code Online (Sandbox Code Playgroud)
和dll B必须包括:
template class Singleton<Logger>;
Run Code Online (Sandbox Code Playgroud)
这仍然会导致创建多个模板实例.我尝试将extern放在所有的dll中但它仍然无法工作我尝试从所有dll中移除extern并且它仍然无法工作.这不是实现模板单例的标准方法吗?这样做的正确方法是什么?
这样做的"正确"方法是......不使用单身人士.
如果您希望所有其他代码使用某种类型的相同实例,则为该代码提供对该实例的引用 - 作为函数或构造函数的参数.
使用单例(非模板)与使用全局变量完全相同,这是您应该避免的做法.
使用模板意味着编译器决定如何实例化代码,以及如何访问"实例".您遇到的问题是这个和在DLL中使用静态的组合.
单身人士不好的原因有很多,包括终身问题(确切地说,删除单身人员是否安全?),线程安全问题,全局共享访问问题等等.
总之,如果您只想要一个事物的一个实例,只需创建它的一个实例,并将其传递给需要它的代码.
对我__declspec(dllexport)有用的技巧是添加到单例的模板定义中; 从类定义中拆分模板实现,只包含A DLL中的实现; 最后,通过创建一个调用的虚函数强制模板在A DLL中实例化Singleton<Logger>::instance().
因此,在A DLL的头文件中,您可以像这样定义Singleton模板:
template <class T>
class __declspec(dllexport) Singleton {
public:
static T &instance();
};
Run Code Online (Sandbox Code Playgroud)
然后在你的A DLL的cpp文件中定义模板实现,并强制实例化Singleton<Logger>如下:
template <class T>
T &Singleton<T>::instance() {
static T _instance;
return _instance;
};
void instantiate_logger() {
Singleton<Logger>::instance();
}
Run Code Online (Sandbox Code Playgroud)
至少使用我的编译器,我不需要instantiate_logger从任何地方打电话.只是存在它会强制生成代码.因此,如果此时转储A DLL的导出表,您应该看到一个条目Singleton<Logger>::instance().
现在在您的C DLL和D DLL中,您可以包含带有模板定义的头文件Singleton,但由于没有模板实现,编译器将无法为该模板创建任何代码.这意味着链接器最终会抱怨未解析的外部因素Singleton<Logger>::instance(),但您只需链接A DLL的导出库即可解决此问题.
底线是代码Singleton<Logger>::instance()只在DLL A中实现,因此您永远不会有多个实例.
MSDN说
Win32 DLL映射到调用进程的地址空间.默认情况下,使用DLL的每个进程都有自己的所有DLL全局和静态变量的实例.如果您的DLL需要与其他应用程序加载的其他实例共享数据,您可以使用以下任一方法:
Run Code Online (Sandbox Code Playgroud)Create named data sections using the data_seg pragma. Use memory mapped files. See the Win32 documentation about memory mapped files.
http://msdn.microsoft.com/en-us/library/h90dkhs0%28v=vs.80%29.aspx
| 归档时间: |
|
| 查看次数: |
3980 次 |
| 最近记录: |