首页 > 解决方案 > 静态变量在 DLL 中定义的模板类使用中重复

问题描述

我在一个名为 TemplateT 的头文件中的 DLL 中有以下代码:

#pragma once

template<class T>
class __declspec(dllexport) TemplateT {
public:
    static int number;
    TemplateT(int num) {
        number = num;
    }
    int getNumber() {
        return number;
    }

};
template<class T>
int TemplateT<T>::number;

在另一个名为 Exported.h 的头文件中

#pragma once
#include "TemplateT.h"


#define EXPORTED __declspec(dllexport)

extern EXPORTED TemplateT<int> exported;

在 Exported.cpp 我有:

#include "Exporter.h"


TemplateT<int> exported(5);

如您所见,我将静态成员“数字”初始化为 5。但是当我从另一个项目访问变量时,如下所示:

#include <iostream>
#include "Exporter.h"

int main()
{
    int a = exported.getNumber();
    int b = 0;
}

我看到 number 的值为 0。如果你能向我解释这种行为,我会很高兴。

编辑

两者都与 Visual Studio 2019 一起使用。dll 使用 vs19 编译,另一个项目使用 vs10

我发现了一个关于同样情况的问题,但那里的答案并没有为我解决问题

静态成员的两个实例

标签: templateswinapivisual-c++dlldllexport

解决方案


#include 指令实际上意味着包含。它有效地将包含的头文件的内容插入源文件(.c/.cpp)(递归)。

因此,当您(直接或间接)将您的 template.h 包含在多个源文件中时,每个源文件都会分配它自己的静态number文件。如果将这些源文件编译成一个目标文件,就会出现链接错误。但如果它们被编译成不同的 DLL/EXE,它们将保留自己的静态文件副本。

这类似于全局变量,其中您通常必须使用extern关键字告诉编译器这只是一个声明,而不是定义。


推荐阅读