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.
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:
//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.
The following main.cpp is an example:
//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.
std::type_info
, the result of thetypeid
operator, was invented for. It even has the mechanics to be used as a map key. – Discrimination