c++ - 显然,静态变量将其值重置为 0

标签 c++ static

我有一个名为 Component 的基类,它有许多派生自它的类。我希望每个类都有一个与之关联的整数(哪个组件获得什么值无关紧要,只要它们从 0 开始并且是连续的)。我不知道如何直接执行此操作,因此在与 Component 相同的文件中,我添加了以下内容:

template <typename T>
class ComponentIdentifier
{
public:
    static unsigned int cid;
};

static unsigned int CIDCounter = 0;
template <typename T> unsigned int ComponentIdentifier<T> = CIDCounter++;

template <typename T> unsigned int ComponentID()
{
    return ComponentIdentifier<T>::cid;
}

unsigned int ComponentCount(); // Defined in .cpp file, just returns CIDCounter

现在我测试了 ComponentID() 函数,它似乎工作正常。正如我预期的那样,我在 ComponentID 上尝试的每个组件类都返回了一个不同的整数。但是,每当我调用 ComponentCount 时,我都会得到 0。

例如如果我有以下代码行:

std::cout << ComponentID<AAA>() << std::endl;
std::cout << ComponentID<BBB>() << std::endl;
std::cout << ComponentID<CCC>() << std::endl;
std::cout << ComponentCount() << std::endl;

那么我的输出是:

0
1
2
0

我怀疑正在发生的事情是 CIDCounter 在用于设置每个组件的 cid 之后再次设置为 0,但我不确定,这看起来有点奇怪。有没有办法做我想做的事,或者我疯了,整个计划注定要失败?

最佳答案

您已将标识符声明为静态:

static unsigned int CIDCounter = 0;

这意味着每个编译单元都会得到自己的变量拷贝。相反,您应该在头文件中将其声明为 extern:

extern unsigned int CIDCounter;

并在实现文件中初始化

unsigned int CIDCounter = 0;

应该注意,如果没有适当的锁,这将不是线程安全的。

进一步澄清:

此上下文中的static 关键字表示变量或函数仅限于当前编译单元(通常是cpp 文件)。我猜你有一个 main.cpp 和一个 idcounter.cpp - 所以现在我们有两个变量(每个编译单元一个)main_CIDCounteridcounter_CIDCounter(变量名称仅供说明!)。

当您在 main.cpp 中执行测试代码时,模板函数会看到 main_CIDCounter,因为这是当前编译单元,您会得到预期的 1、2、3。但是,当您从 idcounter.cpp 调用 ComponentCount() 代码时,该代码会看到 idcounter_CIDCounter - 尚未修改全部。如果您有其他编译单元,您会看到类似的行为,其中每个 cpp 文件似乎都在维护自己的 ID 计数器。

我所描述的修复只是在 idcounter.cpp 中只有一个 CIDCounter 拷贝,并在所有其他编译单元中将其声明为外部。

关于c++ - 显然,静态变量将其值重置为 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4448296/

相关文章:

java - 使用简单的C程序编译并运行Java程序

c++ - 为什么两个代码给出不同的输出

c++ - 标识符 calcHist() 在 C++ 的 OpenCV 中未定义

c++ - 如何使静态映射<string, TNested> 作为模板类的成员?

C++静态对象类函数

带有 static 关键字的 JavaFX 问题;带有最小的、完整的和可验证的示例

c++ - 在 SQLite 中存储 `std::tm`

c++ - 为什么当我删除其他字符时最后一个字符会加倍,如何防止这种情况发生?

java - java中静态方法与实例字段的通信

java - 从其他类引用 MainActivity 中的静态上下文是否不好?