我有一个名为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。
e.g。如果我有以下几行代码:
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,但我不确定并且这看起来有点奇怪。有没有办法做我想做的事情,还是我疯了,整个计划注定要失败?
答案 0 :(得分:9)
您已将您的标识符声明为静态:
static unsigned int CIDCounter = 0;
这意味着每个编译单元将获得自己的变量副本。相反,您应该在头文件中将其声明为extern:
extern unsigned int CIDCounter;
并在实现文件
中初始化它unsigned int CIDCounter = 0;
应该注意,如果没有适当的锁定,这将不是线程安全的。
进一步澄清:
此上下文中的static
关键字表示变量或函数仅限于当前编译单元(通常是cpp文件)。我猜你有main.cpp
和idcounter.cpp
- 所以现在我们有两个变量(每个编译单元一个)main_CIDCounter
和idcounter_CIDCounter
(变量名仅供参考!)。
当您在main.cpp中执行测试代码时,模板函数会看到main_CIDCounter
,因为这是当前的编译单元,您将得到预期的1,2,3。但是,当您使用来自ComponentCount()
的{{1}}代码时,该代码会看到idcounter.cpp
- 它根本没有被修改过。如果您有其他编译单元,您会看到类似的行为,其中每个cpp文件似乎都维护着自己的ID计数器。
我所描述的修复只是在idcounter_CIDCounter
中只有CIDCounter
的一个副本,并在所有其他编译单元中将其声明为外部。