Having class TaskBase
, each derived class of it must have name and unique id.
The TaskBase
is something like below:
class TaskB
I suggest implementing pure virtual methods for obtaining the class name and ID in the base class. The descendants would need to provide the unique names and IDs.
class TaskBase
{
public:
virtual std::string get_task_name(void) const = 0;
virtual unsigned long get_task_id(void) const = 0;
};
I took @VoidStar's suggest a step further and put the names into a (single) common class:
class TaskNames
{
protected:
static std::string get_tas1_name();
};
class Task1: public TaskBase, public TaskNames
{
//...
};
class TaskBase
{
private:
const void* m_id;
string m_name;
public:
TaskBase(const void* m_id, string m_name): m_id(m_id), m_name(m_name)
{
}
const void* id() const
{
return m_id;
}
string name() const
{
return m_name;
};
};
template< typename DERIVED >
class TaskProxy: public TaskBase
{
public:
static const void* id()
{
//if you want to have for each object a unique id:
//return reinterpret_cast<void*>(this);
//just for each TaskProxy<????>:
return reinterpret_cast<const void*>(typeid( DERIVED ).name());
}
static string name()
{
return typeid( DERIVED ).name();
}
TaskProxy(): TaskBase(id(), name()) {}
};
Usage:
class MyTask1 : public TaskProxy< MyTask1 >
{
};
class MyTask2 : public TaskProxy< MyTask2 >
{
};
...
MyTask1 myTask1;
TaskBase *baseA = &myTask1;
MyTask2 myTask2;
TaskBase *baseB = &myTask2;
cout << "Name: " << baseA->name() << " Id:" << baseA->id() << endl;
cout << "Name: " << baseB->name() << " Id:" << baseB->id() << endl;
Which outputs this (with gcc 4.6):
Name: 7MyTask1 Id:0x401228
Name: 7MyTask2 Id:0x4011c0
If you are following strictly standard C++, you may need to just bite the bullet and do some additional bookkeeping. Make an enum somewhere that stores all the classnames:
enum ClassID {
MYTASK1_CLASS,
MYTASK2_CLASS
};
It doesn't take that long to add a new classId when you make a new class.
I've done this before. It's sufficient for uniqueness to do what I describe above. But... if the enum values are set with a clever enough macro, you can encode the hierarchy of the classes, and implement dynamic cast and instanceof solely from the ClassID and a bitwise mask!