【问题标题】:static counter in c++C++中的静态计数器
【发布时间】:2012-06-08 12:46:39
【问题描述】:

我正在尝试创建一个 Data 类,其对象每个都拥有一个唯一的 ID。

我希望第一个对象的 ID 为 1,第二个对象的 ID 为 2,等等。我必须使用 static int,但所有对象具有相同的 ID,而不是 1、2、 3...

这是Data 类:

class Data
{
private:
   static int ID;
public:
   Data(){
   ID++;
   }
};

我该怎么做才能让第一个 ID 为 1,第二个 ID 为 2,依此类推?

【问题讨论】:

  • 确保你处理好多线程,因为变量是static
  • 通常人们使用long而不是int
  • @shan:哪些人?可以是他想要的任何东西。
  • @0A0D longint 宽。如果我们不知道我们想要多少个对象,最好使用long
  • @shan:它将回滚到负数(如果它是无符号的,则返回零)。 long 最终也会翻车。 Unsigned int 转到 65535。这完全取决于应用程序。

标签: c++ class static counter


【解决方案1】:

这个:

class Data
{
private:
   static int ID;
   const int currentID;
public:
   Data() : currentID(ID++){
   }
};

除了静态计数器,您还需要一个实例绑定成员。

【讨论】:

  • 会员ID应该是const字段。一旦创建了对象,更改它可能几乎没有意义。它还将自动禁止operator= 覆盖对象的 id,即使用户有责任提供不重用源对象 id 的复制构造函数。
  • 我在使用const 时遇到了一些错误,这可能是由于我的用户声明的复制构造函数。见this answer。删除const“固定”这个,当然这意味着变量不是const
  • 这里将ID初始化为什么值,如何初始化?
  • @dekuShrub 初始化被忽略了,布雷迪的回答中有一个例子。
  • 我认为可能是这种情况,但不确定,因为当我尝试不使用它时我的 linter 没有抱怨,谢谢! ^^
【解决方案2】:

如果 ID 是静态的,那么它将对所有类实例具有相同的值。

如果您希望每个实例具有连续的 id 值,那么您可以将静态属性与类变量结合起来,如下所示:

class Data
{
private:
   static int ID;
   int thisId;
public:
   Data(){
   thisId = ++ID;
   }
};

int Data::ID = 0;

如果应用程序将是多线程的,那么您必须将其与 pthread 互斥锁之类的东西同步。

【讨论】:

  • 谢谢,考虑过这个解决方案,但我想知道是否有另一种方法可以做到这一点,只能使用静态 int,因为我被要求只使用静态 int。谢谢! :)
  • @Jjang,如果你只是在构造函数中打印值,你可以只用一个静态 int 来完成,但如果你需要 store唯一的顺序值,那么您需要的不仅仅是静态 int。
  • @Jjang:你不能让每个对象的 unique id 都只有一个 shared id (static),这完全没有意义。
【解决方案3】:

允许在函数中初始化静态变量,因此解决方案可以是这样的

 class Data
 {
    private:
    static int ID ()
    {
       static int ID = 0;
       return ID ++;
    }
    int myId;

    public:
    Data(): myId (ID ())
    {      
    }
 };

【讨论】:

    【解决方案4】:

    Data 的每个实例都需要自己的非静态成员变量来存储其 ID。 static 变量可用于存储上次使用的 ID,该 ID 将在 Data 的构造函数中递增。

    考虑使用boost's uuid,而不是static 计数器,它不是线程安全的:

    #include <boost/lexical_cast.hpp>
    #include <boost/uuid/uuid.hpp>
    #include <boost/uuid/uuid_generators.hpp>
    #include <boost/uuid/uuid_io.hpp>
    
    using boost::lexical_cast;
    using boost::uuids::uuid;
    using boost::uuids::random_generator;
    
    std::string id_ = lexical_cast<std::string>((random_generator())());
    

    【讨论】:

      【解决方案5】:

      这里的实例(非静态)ID 在哪里?您需要像这样声明一个新的实例 ID 字段

      int m_ID;
      

      然后在你的构造函数中做

      Data(){m_ID = ::InterlockedIncrement(&ID);}
      

      interlocked 或其他线程安全的方式

      【讨论】:

      • 好主意,但它的便携性如何?
      • 当然不便携 ;-) 我只是举个例子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-15
      • 2012-09-28
      • 1970-01-01
      相关资源
      最近更新 更多