Как говорит Альф, в этом не должно быть необходимости. typeid
уже дает уникальный идентификатор класса, хотя идентификатор не является целым числом. Просто для смеха, если мне позволят ослабить условие «общего базового класса», то:
inline unsigned int counter() {
static unsigned int count = 0;
return ++count;
}
struct BaseClass {
virtual unsigned int GetID() = 0;
virtual ~BaseClass() {}
};
template <typename D>
struct IntermediateClass : BaseClass {
virtual unsigned int GetID() {
static unsigned int thisid = counter();
return thisid;
}
};
// usage
struct Derived : IntermediateClass<Derived> {
...
};
Вам необходимо добавить безопасность потоков в counter
, если она будет использоваться в многопоточных программах.
Очевидно, что идентификатор является уникальным только при данном запуске программы.
Это немного затруднительно, если ваша иерархия наследования глубока и если у вас много конструкторов с разными сигнатурами для разных классов, потому что вам нужно вставить IntermediateClass между каждым производным классом и его прямым базовым классом. Но из всего этого всегда можно выручить:
inline unsigned int counter() {
static unsigned int count = 0;
return ++count;
}
struct BaseClass {
virtual unsigned int GetID() = 0;
virtual ~BaseClass() {}
};
template <typename D>
unsigned int ThisID(const D *) {
static unsigned int thisid = counter();
return thisid;
}
// usage
struct Derived : BaseClass {
// this single line pasted in each derived class
virtual unsigned int GetID() { return ThisID(this); }
...
};
Я полагаю, что здесь есть «возможность» для новой языковой функции: виртуальная функция, которая определена в базовом классе как функция шаблона с одним параметром шаблона «typename» и которая автоматически переопределяется в каждом производном классе, используя это производный класс в качестве аргумента шаблона. Мнимый синтаксис, поскольку функции виртуального шаблона недопустимы:
struct BaseClass {
template <typename Derived>
virtual unsigned int GetID() {
static unsigned int thisid = counter();
return thisid;
}
virtual ~BaseClass() {}
};
Трудно обосновать языковую особенность на основании желания заново внедрить RTTI, ум ...