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