如何使用整数 id 自动标识类层次结构中的类
How to use an integer id to identify a class in a class hierarchy automatically?
例如,我有一个基类A
及其子类B
,C
等等。 B
和C
也可以有其子类。结构是一棵根A
树。树中的每个类都被分配了一个不同的整数来标识自己。整数 id 的值和顺序没有限制。只要确保它们对于不同的类是不同的。
我的问题是如何通过使用类似的模板技术来巧妙地(或自动)做到这一点,因为手动分配很容易出错。任何获取 id 的方法都可以,例如
class A
{
public:
static const id = ...;
};
或
template<class A>
struct Id
{
enum { value = ... };
};
最简单的方法只是一个函数
int nextId() {
static int rval = 1;
return rval++;
}
class A { public: static const id = nextId(); };
class B { public: static const id = nextId(); };
class C { public: static const id = nextId(); };
只要您不需要在程序开始时在动态初始化中使用 ID,这将起作用。
编辑:如果这还不够,下一步是对模板中的静态变量做同样的事情。 这适用于跨编译单元,但仍然是动态初始化时间。
template <typename DummyT = void>
struct CommonCounter
{
public:
static int nextId() {
static int rval = 1;
return rval ++;
}
};
template <typename T>
struct IdFor
{
static int value()
{
static int rval = CommonCounter<>::nextId();
return rval;
}
};
class A { public: static const id = IdFor<A>::get(); };
你可以做这样的事情。这应该在同一编译器上给出相同的顺序。您还可以修改键入内容的方式,以获取已知订单并在初始化时检测问题。简单的实施,未经测试。
#include <typeinfo>
class A {
public:
virtual ~A();
static void register_type(std::type_info const& t);
int id() const;
};
template<class T>
struct DoInitA
{
DoInitA() { A::register_type(typeid(T)); }
};
class B : public A
{
static DoInitA<B> s_a_init;
public:
~B() { }
};
//
// Implementation file.
//
#include <vector>
#include <functional>
namespace {
struct TypeinfoLess {
typedef std::reference_wrapper<const std::type_info> value_type;
bool operator()(value_type const& lhs, value_type const& rhs) const {
return lhs.get().before(rhs.get());
}
};
}
typedef std::vector<std::reference_wrapper<const std::type_info>> TypeVector;
static TypeVector s_types;
static bool s_init_complete = false;
A::~A() { }
void A::register_type(std::type_info const& t)
{
static int s_counter = 0;
if (s_init_complete)
throw std::runtime_error("Late initialisation");
s_types.push_back(std::reference_wrapper<const std::type_info>(t));
}
int A::id() const
{
if (!s_init_complete) {
sort(s_types.begin(), s_types.end(), TypeinfoLess());
s_init_complete = true;
}
for (size_t i = 0; i < s_types.size(); ++i)
if (s_types[i].get() == typeid(*this)) return i;
throw std::runtime_error("Uninitialised type");
}
相关文章:
- 如何重构类层次结构以避免菱形问题
- C++ 中模板化类型的类层次结构
- 为什么不同类型层次结构的指针之间的dynamic_cast定义得很好?
- 继承层次结构并将元素添加到向量
- C++ 类层次结构中的"对齐"是什么意思?
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 类层次结构中的运算符重载
- 如何在层次结构中实现运算符使用?
- 反向层次结构中的可变参数模板参数
- 如何在继承层次结构中调用具有默认参数的构造函数?
- C++ 提升 - 包含类层次结构对象的类的序列化
- 在C++继承层次结构时提取实现者
- 在C++中将类实例添加到对象层次结构中的问题
- 确定大层次结构中基本指针的实际类型,无需dynamic_cast
- 在继承层次结构中复制和移动
- 模板冲突的类型-但类型应该是相同的cfr类层次结构
- 删除父/子窗口层次结构的最佳方法
- 是否可以使一个类成为两个不同层次结构的子类?
- 有没有更好的方法来处理将标识分配给层次结构中的类以供运行时使用
- 如何使用整数 id 自动标识类层次结构中的类