I have a bunch of C++ classes.
我有一堆C ++类。
I want each class to have something like:
我希望每个班级都有类似的东西:
static int unique_id;
All instances of a same class should have the same unique_id; different classes should have different unique_id's.
同一个类的所有实例应该具有相同的unique_id;不同的类应该有不同的unique_id。
The simplest way to do this appears to be threading a singleton through the classes.
最简单的方法似乎是通过类线程化单例。
However, I don't know what's called when for static class members / things that happen before main.
但是,我不知道什么时候静态类成员/事件发生在main之前。
(1) if you have a solution that does not involve using singleton, that's fine too
(1)如果你有一个不涉及使用单身的解决方案,那也没关系
(2) if you have a solution that gives me a :
(2)如果你有一个解决方案给我一个:
int unique_id();
that is fine too.
那很好。
Thanks!
6 个解决方案
#1
9
Have a class that increments it's ID on each creation. Then use that class as a static field in each object that is supposed to have an ID.
有一个类在每次创建时增加它的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();
}
};
#2
4
Building on Kornel's solution:
以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();
Use it like this:
像这样用它:
class my_class : public id_base<my_class> {
// ...
};
#3
3
Actually that's very similar to RTTI. To achieve (2), C++'s buildin RTTI can be exploited. Call typeid
on *this
, and take the address of the typeinfo as unique ID.
实际上这与RTTI非常相似。为了实现(2),可以利用C ++的buildin RTTI。在* this上调用typeid,并将typeinfo的地址作为唯一ID。
Conss: a) IDs aren't be fixed (recompile would change them), and b) the information is only available given an instance of the class, c) it's ugly.
Conss:a)ID不是固定的(重新编译会改变它们),b)信息仅在给定类的实例时可用,c)它很难看。
Why do you want this?
你为什么要这个?
#4
1
C++ has this already built in.
C ++已经内置了这个。
You can use the typeid
operator to return a type_info
class. The type_info:name()
will return the (unique) name of the class.
您可以使用typeid运算符返回type_info类。 type_info:name()将返回类的(唯一)名称。
#5
1
First, why? In any case, you can manually set the IDs easily:
首先,为什么?无论如何,您可以轻松地手动设置ID:
template <int id>
struct base { enum { unique_id = id }; };
class foo: public base<5> { ... };
class bar: public base<10> { ... };
Then
foo x;
bar y;
assert(x.unique_id == 5);
assert(y.unique_id == 10);
Of course, you'll have to manually keep track of the IDs for each class; at this point, I'll ask the original question: why?
当然,您必须手动跟踪每个类的ID;在这一点上,我会问原来的问题:为什么?
#6
1
I have recently found sbi's version of Kornel's solution to be very useful. Thank you both for providing your answers. However, I wanted to extend the solution further so that several types of IDs can be easily created without creating a separate pair of id_impl and id_base classes for each new type.
我最近发现sbi版的Kornel解决方案非常有用。谢谢你们提供答案。但是,我想进一步扩展解决方案,以便可以轻松创建几种类型的ID,而无需为每种新类型创建单独的id_impl和id_base类。
To do this I templated the id_impl class, and added another argument to the id_base. The result is encapsulated in a header file that is included anywhere one wants to add a new ID type:
为此,我模板化了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();
For my application I wanted several abstract base classes to have an ID type associated with them. So for each instance of the GeneralIDbase template the types specified are: the abstract base class of the derived class being declared, and the derived class being declared.
对于我的应用程序,我希望有几个抽象基类具有与之关联的ID类型。因此,对于GeneralIDbase模板的每个实例,指定的类型是:声明的派生类的抽象基类,以及声明的派生类。
The following main.cpp is an example:
以下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;
}
The output of this code is
这段代码的输出是
/*
objA1.GetID() = 1
objA2.GetID() = 2
objB1.GetID() = 1
objB2.GetID() = 2
*/
I hope this helps! Please let me know of any issues.
我希望这有帮助!如有任何问题,请告诉我。
#1
9
Have a class that increments it's ID on each creation. Then use that class as a static field in each object that is supposed to have an ID.
有一个类在每次创建时增加它的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();
}
};
#2
4
Building on Kornel's solution:
以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();
Use it like this:
像这样用它:
class my_class : public id_base<my_class> {
// ...
};
#3
3
Actually that's very similar to RTTI. To achieve (2), C++'s buildin RTTI can be exploited. Call typeid
on *this
, and take the address of the typeinfo as unique ID.
实际上这与RTTI非常相似。为了实现(2),可以利用C ++的buildin RTTI。在* this上调用typeid,并将typeinfo的地址作为唯一ID。
Conss: a) IDs aren't be fixed (recompile would change them), and b) the information is only available given an instance of the class, c) it's ugly.
Conss:a)ID不是固定的(重新编译会改变它们),b)信息仅在给定类的实例时可用,c)它很难看。
Why do you want this?
你为什么要这个?
#4
1
C++ has this already built in.
C ++已经内置了这个。
You can use the typeid
operator to return a type_info
class. The type_info:name()
will return the (unique) name of the class.
您可以使用typeid运算符返回type_info类。 type_info:name()将返回类的(唯一)名称。
#5
1
First, why? In any case, you can manually set the IDs easily:
首先,为什么?无论如何,您可以轻松地手动设置ID:
template <int id>
struct base { enum { unique_id = id }; };
class foo: public base<5> { ... };
class bar: public base<10> { ... };
Then
foo x;
bar y;
assert(x.unique_id == 5);
assert(y.unique_id == 10);
Of course, you'll have to manually keep track of the IDs for each class; at this point, I'll ask the original question: why?
当然,您必须手动跟踪每个类的ID;在这一点上,我会问原来的问题:为什么?
#6
1
I have recently found sbi's version of Kornel's solution to be very useful. Thank you both for providing your answers. However, I wanted to extend the solution further so that several types of IDs can be easily created without creating a separate pair of id_impl and id_base classes for each new type.
我最近发现sbi版的Kornel解决方案非常有用。谢谢你们提供答案。但是,我想进一步扩展解决方案,以便可以轻松创建几种类型的ID,而无需为每种新类型创建单独的id_impl和id_base类。
To do this I templated the id_impl class, and added another argument to the id_base. The result is encapsulated in a header file that is included anywhere one wants to add a new ID type:
为此,我模板化了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();
For my application I wanted several abstract base classes to have an ID type associated with them. So for each instance of the GeneralIDbase template the types specified are: the abstract base class of the derived class being declared, and the derived class being declared.
对于我的应用程序,我希望有几个抽象基类具有与之关联的ID类型。因此,对于GeneralIDbase模板的每个实例,指定的类型是:声明的派生类的抽象基类,以及声明的派生类。
The following main.cpp is an example:
以下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;
}
The output of this code is
这段代码的输出是
/*
objA1.GetID() = 1
objA2.GetID() = 2
objB1.GetID() = 1
objB2.GetID() = 2
*/
I hope this helps! Please let me know of any issues.
我希望这有帮助!如有任何问题,请告诉我。