I have a base class called Component
which has a number of classes derived from it. I want each class to have an integer associated with it (doesn't matter which component gets what value, as long as they start at 0 and are contiguous). I don't know how to do this directly, so in the same file as Component
I added the following:
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
Now I tested the ComponentID() function and it appears to work fine. Each component class that I tried ComponentID on returned a different integer just as I expected. However, whenever I call ComponentCount I get 0.
e.g. if I have the following lines of code:
std::cout << ComponentID<AAA>() << std::endl;
std::cout << ComponentID<BBB>() << std::endl;
std::cout << ComponentID<CCC>() << std::endl;
std::cout << ComponentCount() << std::endl;
then my output is:
0
1
2
0
I suspect what's happening is that CIDCounter is being set to 0 again after its used to set the cid's of each component, but I don't know for sure and that seems kind of weird. Is there a way to do what I want or am I crazy and this whole plan doomed to failure?
You've declared your identifier as static:
static unsigned int CIDCounter = 0;
which means each compilation unit will get its own copy of the variable. Instead you should declare it as extern in the header file:
extern unsigned int CIDCounter;
and initialise it in the implementation file
unsigned int CIDCounter = 0;
One should note that without appropriate locks this won't be thread-safe.
To clarify further:
The static
keyword in this context means that the variable or function is limited to the current compilation unit (usually a cpp file). I'm guessing you have, say, a main.cpp
and an idcounter.cpp
- so now we have two variables (one for each of the compilation units) main_CIDCounter
and idcounter_CIDCounter
(variable names are for explanation only!).
When you execute your test code in main.cpp the template function sees main_CIDCounter
because that's the current compilation unit and you get the expected 1,2,3. However, when you call ComponentCount()
code from idcounter.cpp
is used, and that code sees idcounter_CIDCounter
- which hasn't been modified at all. If you had other compilation units you would see similar behaviour, where each cpp file would appear to be maintaining its own ID counter.
The fix I've described is simply to only have one copy of CIDCounter
in idcounter.cpp
, and declare it as external in all the other compilation units.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With