5

我有一堆 C++ 类。

我希望每个班级都有类似的东西:

static int unique_id;

同一类的所有实例都应具有相同的 unique_id;不同的类应该有不同的unique_id。

执行此操作的最简单方法似乎是通过类将单例线程化。

但是,我不知道什么时候调用静态类成员/在 main 之前发生的事情。

(1) 如果您有一个不涉及使用单例的解决方案,那也没关系

(2) 如果您有一个解决方案,可以给我:

int unique_id(); 

那也很好。

谢谢!

4

6 回答 6

7

有一个在每次创建时递增其 ID 的类。然后将该类用作每个应该具有 ID 的对象中的静态字段。

class ID
{
    int id;
public:
    ID() {
        static int counter = 0;
        id = counter++;
    }

    int get_id() {  return id; }
};

class MyClass
{
    static ID id;
public:
    static int get_id() 
    {
        return id.get_id();
    }
};
于 2010-01-31T19:02:57.330 回答
3

基于Kornel 的解决方案

class id_impl {
  private:
    id_impl() {}
    static int get_next_id()
    {
      static int counter = 0;
      return ++counter;
    }
    template< class T >
    friend class id_base;
};

template< class T >
class id_base : private id_impl
{
  public:
    static int get_id() { return id; }
  private:
    static int id;
};

template< class T >
int id_base<T>::id id = get_next_id();

像这样使用它:

class my_class : public id_base<my_class> {
  // ...
};
于 2010-01-31T19:38:03.307 回答
2

实际上,这与 RTTI 非常相似。为了实现 (2),可以利用 C++ 的内置 RTTI。调用typeid*this并将 typeinfo 的地址作为唯一 ID。

缺点:a)ID 不是固定的(重新编译会改变它们),b)信息仅在给定类的实例时可用,c)它很难看。

你为什么要这个?

于 2010-01-31T19:11:14.460 回答
0

首先,为什么?在任何情况下,您都可以轻松地手动设置 ID:

template <int id>
struct base { enum { unique_id = id }; };

class foo: public base<5> { ... };
class bar: public base<10> { ... };

然后

foo x;
bar y;
assert(x.unique_id == 5);
assert(y.unique_id == 10);

当然,您必须手动跟踪每个类的 ID;在这一点上,我会问原来的问题:为什么?

于 2010-01-31T19:09:28.767 回答
0

C++ 已经内置了这个。

您可以使用typeid运算符返回一个type_info类。将type_info:name()返回类的(唯一)名称。

于 2010-01-31T19:10:05.303 回答
0

我最近发现sbi 的 Kornel 解决方案版本非常有用。谢谢你们两位提供答案。但是,我想进一步扩展解决方案,以便可以轻松创建几种类型的 ID,而无需为每个新类型创建一对单独的 id_impl 和 id_base 类。

为此,我对 id_impl 类进行了模板化,并向 id_base 添加了另一个参数。结果被封装在一个头文件中,该文件包含在任何想要添加新 ID 类型的地方:

//idtemplates.h

template< class T >
class GeneralID 
{
  private:
    GeneralID() {}
    static int GetNextID()
    {
      static int counter = 0;
      return ++counter;
    }
    template< class T, class U >
    friend class GeneralIDbase;
};

template< class T, class U >
class GeneralIDbase : private GeneralID < T >
{
  public:
    static int GetID() { return ID; }
  private:
    static int ID;
};

template< class T, class U >
int GeneralIDbase<T, U>::ID = GetNextID();

对于我的应用程序,我希望几个抽象基类具有与之关联的 ID 类型。因此,对于 GeneralIDbase 模板的每个实例,指定的类型是:正在声明的派生类的抽象基类,以及正在声明的派生类。

以下 main.cpp 是一个示例:

//main.cpp    

#include<iostream>
#include<idtemplates.h>

using namespace std;

class MyBaseClassA {};
class MyBaseClassB {};

class MyClassA1 :public MyBaseClassA, public GeneralIDbase<MyBaseClassA, MyClassA1> {};
class MyClassA2 :public MyBaseClassA, public GeneralIDbase<MyBaseClassA, MyClassA2> {};
class MyClassB1 :public MyBaseClassB, public GeneralIDbase<MyBaseClassB, MyClassB1> {};
class MyClassB2 :public MyBaseClassB, public GeneralIDbase<MyBaseClassB, MyClassB2> {};

    int main()
{
    MyClassA1 objA1;
    MyClassA2 objA2;

    cout << "objA1.GetID() = "  << objA1.GetID() << endl;
    cout << "objA2.GetID() = "  << objA2.GetID() << endl;

    MyClassB1 objB1;
    MyClassB2 objB2;

    cout << "objB1.GetID() = "  << objB1.GetID() << endl;
    cout << "objB2.GetID() = "  << objB2.GetID() << endl;

    cin.get();
    return 0;
}

这段代码的输出是

/*
objA1.GetID() = 1 
objA2.GetID() = 2 
objB1.GetID() = 1 
objB2.GetID() = 2 
*/

我希望这有帮助!请让我知道任何问题。

于 2012-07-29T20:58:42.217 回答