我需要每个派生类都有一个唯一的ID,但ID必须是增量的。 这是我目前的实施:
//component.cpp
class ComponentId
{
public:
ComponentId();
static int nextId;
int id;
};
template<class T>
class Component {
public:
static const ComponentId componentId;
};
template<class T>
const ComponentId Component<T, chunkSize>::componentId;
///component.cpp
int ComponentId::nextId = 0;
ComponentId::ComponentId() : id(nextId++)
{
}
//IN static library a
struct compA : public Component<compA> {
}
//In static library b
struct compB : public Component<compB> {
}
//in main.cpp
#include <component.h>
#include <compA.h>
#include <compB.h>
std::cout << compA::componentId.id << std::endl;
std::cout << compB::componentId.id << std::endl;
这在我的所有单元测试中都能正常工作,但在使用多个编译单元或跨静态库时似乎没有按预期工作。 ID在不同的库中重复使用。一个库可能具有id 0,1,2和3,但是另一个库也将具有ID为0和1的类。 我的猜测是nextid字段没有被共享。
我也试过使用extern关键字,但似乎产生了同样的问题。 我还尝试创建一个静态getId函数,希望在第一次使用时进行初始化,但没有这样的运气。
我真的需要这些ID是紧密的,如1,2,3,4,5,而不是67,80,123,1,4。
有什么想法吗?
答案 0 :(得分:0)
假设您希望在多个TU之间共享一个int
实例,我认为使用返回inline
引用的static int
函数应该可以解决这个问题:
// counter.hpp
namespace detail
{
inline int& getCounter()
{
static int result{0};
return result;
}
}
inline int nextId()
{
return detail::getCounter()++;
}
// component.cpp
ComponentId::ComponentId() : id(nextId())
{
}
然而,这感觉很脆弱并且容易出错,特别是如果您的目标是依靠您的ID进行序列化/反序列化。如果您在编译时了解组件的所有类型,我建议使用类型列表。 E.g。
using components = typelist<
Component0,
Component1,
Component2,
Component3
>;
否则,如果您只在运行时知道组件类型,请提供某种允许用户以受控方式注册/取消注册类型的注册表。