16

我有几个对象,需要为它们生成一个唯一标识符,在每个对象的生命周期内不会更改/重复。

基本上我想为我的对象获取/生成一个唯一的 id,像这样

int id = reinterpret_cast<int>(&obj);

或者

int id = (int)&obj;

我知道上面的代码是坏主意,因为 int 可能不够大,无法存储地址等。

那么从对象中获取唯一标识符的最佳实践是什么,这将是一个可移植的解决方案?

4

6 回答 6

18

根据您的“独特性”要求,有几种选择:

  • 如果在一个地址空间内(“在一个程序执行内”)是唯一的,并且您的对象保持在内存中的位置,那么指针就可以了。但是有一些陷阱:如果您的对象存在于容器中,则每次重新分配都可能更改对象的身份,并且如果您允许复制对象,则从某些函数返回的对象可能已在同一地址创建。
  • 如果您需要更全局的唯一性,例如因为您正在处理通信程序或持久数据,请使用 GUID/UUId,例如boost.uuid
  • 您可以从某个静态计数器创建唯一整数,但要注意以下陷阱:
    • 确保你的增量是原子的
    • 防止复制或创建您的自定义复制构造函数、赋值语句。

Personally, my choice has been UUIDs whenever I can afford them, because they provide me some ease of mind, not having to think about all the pitfalls.

于 2013-01-29T14:56:09.377 回答
11

如果对象需要唯一标识,可以在构造函数中生成唯一id:

struct Obj
{ 
   int _id;
   Obj() { static int id = 0; _id = id++; }
};

您必须决定如何处理副本/分配(相同的 id - 以上将起作用/不同的 id - 您将需要一个复制构造函数,并且可能需要一个static类成员而不是static局部变量)。

于 2013-01-29T14:39:41.773 回答
5

当我研究这个问题时,我很快就找到了Boost UUID 库(通用唯一标识符,http://www.boost.org/doc/libs/1_52_0/libs/uuid/)。但是,随着项目的增长,我切换到Qt 的 GUID库(全局唯一标识符,https://doc.qt.io/qt-5/quuid.html)。

不过,对我来说,一个教训是开始声明你自己的 UUID 类并隐藏实现,以便以后可以切换到你认为合适的任何东西。

我希望这会有所帮助。

于 2013-01-29T14:43:44.547 回答
0

如果您的对象是一个类,那么您可以有一个静态成员变量,您可以将其设为 0。然后在构造函数中将此值存储到类实例中并递增静态变量:

班级

Indexed
{
public:
   Indexed() :
       m_myIndex( m_nextIndex++ )
   { }

   int getIndex() const
   { return m_myIndex; }

private:
   const int m_myIndex;
   static int m_nextIndex;
};
于 2013-01-29T14:41:41.317 回答
0

直接使用对象地址作为唯一(对于此运行)标识符似乎不是一个坏主意。为什么要把它转换成整数?只需将指针与==

MyObject *obj1, *obj2;
...
if (obj1 == obj2) ...

当然,如果您需要将 ID 写入数据库等,这将不起作用。运行之间可以使用相同的指针值。此外,不要重载比较运算符 ( ==)。

于 2013-01-29T14:44:00.913 回答
0

如果您需要分布式环境的唯一 ID,请使用boost::uuid

于 2013-01-29T14:44:56.633 回答