35

在 C++ 中生成唯一 ID 的最佳算法是什么?长度 ID 应为 32 位无符号整数。

4

6 回答 6

65

获得一个唯一的 32 位 ID 很简单:下一个。工作 40 亿次。136 年独一无二,如果您需要一秒钟。魔鬼在细节中:前一个是什么?您需要一种可靠的方式来持久保存最后使用的值,并需要一种原子方式来更新它。

这有多难取决于 ID 的范围。如果它是一个进程中的一个线程,那么您只需要一个文件。如果它是一个进程中的多个线程,那么您需要一个文件和一个互斥锁。如果一台机器上有多个进程,那么您需要一个文件和一个命名的互斥锁。如果它是多台机器上的多个进程,那么您需要分配一个权威的 ID 提供者,即所有机器都与之通信的单个服务器。数据库引擎就是这样一个常见的提供者,他们有这个内置的特性,一个自动增量列。

随着范围的扩大,获取 ID 的费用会逐渐增加。当它变得不切实际时,范围是 Internet 或提供商太慢或不可用,那么您需要放弃 32 位值。切换到随机值。随机性足以使机器被流星击中的可能性比重复相同 ID 的可能性至少高一百万倍。一个好ID。它只有 4 倍大。

于 2010-01-01T16:29:25.747 回答
15

这是我能想到的最简单的ID。

MyObject obj;
uint32_t id = reinterpret_cast<uint32_t>(&obj);

在任何给定时间,此 ID 在整个应用程序中都是唯一的。没有其他对象将位于同一地址。当然,如果您重新启动应用程序,可能会为该对象分配一个新 ID。一旦对象的生命周期结束,可能会为另一个对象分配相同的 ID。

并且不同内存空间中的对象(例如,在不同的计算机上)可能被分配相同的 ID。

最后但同样重要的是,如果指针大小大于 32 位,则映射将不是唯一的。

但是,由于我们对您想要什么样的 ID 以及它应该有多独特一无所知,所以这似乎是一个很好的答案。

于 2010-01-01T18:01:39.217 回答
8

你可以看到这个。(我认为,完整的答案在 Stack Overflow 上。)
一些关于 Linux 中 C++ 中唯一 ID 的注释在这个站点中。您可以在 Linux 中使用 uuid,请参阅此手册页和示例

如果您使用 windows 并需要 windows API,请参阅此MSDN 页面

这个维基百科页面也很有用:http ://en.wikipedia.org/wiki/Universally_Unique_Identifier 。

于 2010-01-01T14:29:33.120 回答
1
DWORD uid = ::GetTickCount();
::Sleep(100);
于 2010-01-01T14:51:21.907 回答
0

如果你负担得起使用 Boost,那么有一个UUID库应该可以解决问题。使用起来非常简单——检查文档和这个答案

于 2017-08-16T12:31:47.007 回答
-1

几乎没有上下文,但如果您正在为应用程序中的对象寻找唯一 ID,您始终可以使用类似于以下的单例方法

class IDGenerator {
   public:
      static IDGenerator * instance ();
      uint32_t next () { return _id++; }
   private:
      IDGenerator () : _id(0) {}

      static IDGenerator * only_copy;
      uint32_t _id;
}

IDGenerator *
IDGenerator::instance () {
   if (!only_copy) {
      only_copy = new IDGenerator();
   }
   return only_copy;
}

现在,您可以随时通过执行以下操作获得唯一 ID:

IDGenerator::instance()->next ()

于 2010-01-01T16:30:57.953 回答