gpt4 book ai didi

dll 中的 C++ 模板单例

转载 作者:可可西里 更新时间:2023-11-01 14:56:00 29 4
gpt4 key购买 nike

在 dll A 中我有一个模板单例:

template <class T>
class Singleton
{
public:
static T &instance()
{
static T _instance;
return _instance;
}

private:
//All constructors are here
};

在 Dll B 中,我定义了一个类 Logger。 Dll C、D 和 E 使用 Logger,它的访问方式如下:

Singleton<Logger>::instance();

问题是每个dll实例化自己的拷贝

Singleton<Logger>.

而不是使用相同的单例实例。我知道这个问题的解决方案是使用外部模板。即 dll C、D 和 E 必须包含

extern template class Singleton<Logger>;

和 dll B 必须包括:

template class Singleton<Logger>;

这仍然会导致创建多个模板实例。我尝试将 extern 放入所有 dll 中,但仍然无效 我尝试从所有 dll 中删除 extern,但仍然无效。这不是实现模板单例的标准方法吗?执行此操作的正确方法是什么?

最佳答案

对我有用的技巧是添加 __declspec(dllexport)到单例的模板定义;将模板实现从类定义中分离出来,只在A DLL中包含实现;最后,通过创建一个调用 Singleton<Logger>::instance() 的虚拟函数强制在 A DLL 中实例化模板。 .

因此在您的 DLL 的头文件中,您可以像这样定义 Singleton 模板:

template <class T>
class __declspec(dllexport) Singleton {
public:
static T &instance();
};

然后在您的 DLL 的 cpp 文件中定义模板实现,并强制实例化 Singleton<Logger>像这样:

template <class T>
T &Singleton<T>::instance() {
static T _instance;
return _instance;
};

void instantiate_logger() {
Singleton<Logger>::instance();
}

至少对于我的编译器,我不需要调用 instantiate_logger从任何地方。只要它存在就会强制生成代码。因此,如果此时转储 A DLL 的导出表,您应该会看到 Singleton<Logger>::instance() 的条目。 .

现在,在您的 C DLL 和 D DLL 中,您可以包含带有 Singleton 模板定义的头文件。 ,但因为没有模板实现,编译器将无法为该模板创建任何代码。这意味着链接器最终会提示 Singleton<Logger>::instance() Unresolved external 问题,但您只需链接到 A DLL 的导出库中即可修复该问题。

底线是 Singleton<Logger>::instance() 的代码仅在 DLL A 中实现,因此您永远不能拥有多个实例。

关于dll 中的 C++ 模板单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17614172/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com