Jor*_*ans 9 c++ windows templates visual-studio-2010
在DLL中,我有一个带有模板基类的导出的非模板类.此模板基类具有静态成员变量.我在可执行文件中使用静态基本成员,该可执行文件使用导出的非模板类链接到DLL.
在许多情况下,我得到了未解决的外部符号或关于不一致链接的抱怨.我发现一个有效的方案,但它似乎是kludgey所以我想知道是否有更好的方法,如果更好的方式也可能指向VS2010 SP1的C++编译器/链接器的缺陷.
这是我可以提炼的DLL的最小场景 - 我不认为我可以在不破坏场景的情况下删除任何内容.
// Header file
template<typename T>
class _MYDLL_EXPORTS TBaseClass
{
public:
static const double g_initial_value;
};
class _MYDLL_EXPORTS MyClass : public TBaseClass<MyClass>
{
};
// Kludge: use this code only when building the DLL, not when including
// from the DLL's client
#ifdef _MYDLL
template<typename T>
const double TBaseClass<T>::g_initial_value = 1e-5;
#endif
// CPP file
#include "header.h"
// Explicit instantiation of the template for the correct parameter.
template class TBaseClass<MyClass>;
Run Code Online (Sandbox Code Playgroud)
然后是DLL的用户
#include <header.h>
#include <iostream>
int main(void) {
MyClass c;
std::cout << c.g_initial_value;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
通常在 C++ 中,当一个普通类有一个静态成员时,它应该在头文件中声明,但在源文件中实例化。否则会导致创建过多的静态类成员实例。
模板有点类似,除了编译器对模板有一些魔法,而对于非模板则没有。具体来说,它在构建的链接阶段神奇地消除了模板实例化的重复实例。
这是您的问题的根源:_MYDLL 部分中的内容由包含此模板的每个源文件自动实例化,并且还生成 TBaseClass 对象。然后链接器会自动消除重复项。
问题是,您有两个链接:DLL 链接和客户端链接。两者都会创建 TBaseClass 实例化,并且都会创建那些 g_initial_value 对象。
要解决这个问题:将 _MYDLL 条件中的内容移动到 CPP 文件中,这样客户端就不会得到构建实例本身的指令。
归档时间: |
|
查看次数: |
4839 次 |
最近记录: |