我想尝试一个简单的类来进行唯一的ID转换.我正在考虑添加一个静态方法:
class A {
static int const *GetId() {
static int const id;
return &id;
}
};
Run Code Online (Sandbox Code Playgroud)
然后每个类将通过唯一标识int const *.这保证有效吗?返回的指针真的是唯一的吗?有没有更简单的解决方案?
我也想过指向std::type_info:
class A {
static std::type_info const *GetId() {
return &typeid(A);
}
};
Run Code Online (Sandbox Code Playgroud)
那个更好吗?
编辑:
我不需要使用id进行序列化.我只想识别一小组基类,并希望某些类的所有子类具有相同的id
sha*_*oth 10
是的,这会奏效.static在加载模块时,每个本地将被赋予不同的内存位置,并且它将一直存在,直到模块被卸载.请记住,static本地存储在静态存储中,该存储在编译期间分发,并且一直存在直到模块被卸载,因此它们将具有不同的存储位置.
静态变量的地址保证是唯一的,并且在所有翻译单元中都是相同的.
这不是一个好主意,因为它要求您为每个要识别的类添加代码.
类型信息对象的指针不保证是唯一的,但类型信息对象本身保证比较给定的类相等,不同的类不相等.这意味着您可以使用带有类型信息指针的小包装器对象,并委托对类型信息对象进行比较.C++ 11在标准库中有这样的包装器,如果你没有访问权限,那么Andrei Alexandrescu的"现代C++设计"就有一个,因此也许在Loki库中,可能有一个在Boost,我的Wordpress博客上有一个 - 它不像你从头开始发明一个.
但是,如果要将id用于序列化,则需要在构建版本之间有效的id.在这种情况下,您需要字符串或UUID.我会选择UUID.
要将类与UUID相关联,通常可以使用类型特征类.或者,如果您只是进行Windows编程,那么您可以使用Visual C++的语言扩展.我想但我并不是100%确定那些语言扩展也是由g ++实现的(在Windows中).
干杯和hth.
正如我所注意到的,至少 MSVC 2008 或 2010 优化了静态变量,以便以下GetId函数即使对于不同的类也返回相同的地址。
static int const *GetId() {
static const int i = 0;
return &i;
}
Run Code Online (Sandbox Code Playgroud)
因此,未初始化的常量静态变量的地址不能用于标识。最简单的修复方法就是删除const:
static int *GetId() {
static int i;
return &i;
}
Run Code Online (Sandbox Code Playgroud)
另一种生成 ID 的解决方案(似乎可行)是使用全局函数作为计数器:
int Counter() {
static int i = 0;
return i++;
}
Run Code Online (Sandbox Code Playgroud)
然后在需要识别的类中定义如下方法:
static int GetId() {
static const int i = Counter();
return i;
}
Run Code Online (Sandbox Code Playgroud)
由于要定义的方法始终相同,因此可以将其放入基类中:
template<typename Derived>
struct Identified {
static int GetId() {
static const int i = Counter();
return i;
}
};
Run Code Online (Sandbox Code Playgroud)
然后使用一种奇怪的重复模式:
class A: public Identified<A> {
// ...
};
Run Code Online (Sandbox Code Playgroud)