Como dice Alf, esto no debería ser necesario. typeid
ya proporciona un identificador de clase único, aunque el identificador no es un número entero. Apenas para las risas, si se me permite relajar la condición de "clase base común", entonces:
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> {
...
};
Se necesitaría añadir hilo de seguridad en counter
si es para ser utilizado en programas multihilo.
Obviamente, la identificación es única dentro de una ejecución determinada del programa.
se pone un poco difícil si su jerarquía de herencia es profundo, y si usted tiene un montón de constructores con diferentes firmas para diferentes clases, ya que es necesario para insertar IntermediateClass entre cada clase derivada y su clase base directa. Pero siempre se puede rescatar de todo lo que la siguiente manera:
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); }
...
};
Creo que hay una "oportunidad" para una nueva característica del lenguaje aquí: una función virtual que se define en la clase base como una función de plantilla con uno " typename "template parameter, y que se reemplaza automáticamente en cada clase derivada utilizando esa clase derivada como argumento de la plantilla. sintaxis imaginaria, ya que las funciones de plantilla virtuales son ilegales:
struct BaseClass {
template <typename Derived>
virtual unsigned int GetID() {
static unsigned int thisid = counter();
return thisid;
}
virtual ~BaseClass() {}
};
difícil de justificar una característica del lenguaje sobre la base de querer volver a implementar RTTI nosotros mismos, la mente ...
si el ID es int o puede ser de un tipo único, p. Ej. el devuelto por typeid. ¿Tu BaseClass es polimórfico? – Chubsdad
Mi clase base ES polimórfica, pero debido a mi falta de capacidad para encontrar una explicación sólida y exhaustiva sobre la naturaleza exacta de la sobrecarga que acompaña a RTTI (tanto en cuanto a rendimiento como a memoria), intento evitarlo por completo. . – Dan